Improve SenderDeviceAsyncTask

- Use single instance of the async task to transfer all files
This commit is contained in:
Aditya-Sood 2019-08-01 18:36:48 +05:30
parent c590ebabe9
commit ab8e9da971
3 changed files with 59 additions and 57 deletions

View File

@ -47,8 +47,8 @@ public class FileListAdapter extends RecyclerView.Adapter<FileListAdapter.FileVi
if (fileItem.getFileStatus() == SENDING) {
holder.statusImage.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.VISIBLE);
} else if (fileItem.getFileStatus()
!= TO_BE_SENT) { // Icon for TO_BE_SENT is assigned by default in the item layout
} else if (fileItem.getFileStatus() != TO_BE_SENT) {
// Icon for TO_BE_SENT is assigned by default in the item layout
holder.progressBar.setVisibility(View.GONE);
switch (fileItem.getFileStatus()) {

View File

@ -88,8 +88,8 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
@BindView(R.id.text_view_empty_peer_list) TextView textViewPeerDevices;
@BindView(R.id.recycler_view_transfer_files) RecyclerView filesRecyclerView;
private ArrayList<Uri> fileUriArrayList; // For sender device, stores uris of the files
public @NonNull Boolean isFileSender = false;// Whether the device is the file sender or not
private ArrayList<Uri> fileUriArrayList;// For sender device, stores uris of the files
public boolean isFileSender = false; // Whether the device is the file sender or not
public @NonNull WifiDirectManager wifiDirectManager = new WifiDirectManager(this);
@ -104,7 +104,7 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
private boolean fileTransferStarted = false;
private PeerGroupHandshakeAsyncTask peerGroupHandshakeAsyncTask;
private SenderDeviceAsyncTask[] senderDeviceAsyncTaskArray;
private SenderDeviceAsyncTask senderDeviceAsyncTaskArray;
private ReceiverDeviceAsyncTask receiverDeviceAsyncTask;
@Override
@ -295,11 +295,8 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
showToast(this, R.string.preparing_files, Toast.LENGTH_LONG);
for (int i = 0; i < 20000000; i++) ;
senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask[totalFilesForTransfer];
for (int i = 0; i < totalFilesForTransfer; i++) {
senderDeviceAsyncTaskArray[i] = new SenderDeviceAsyncTask(this, i);
senderDeviceAsyncTaskArray[i].execute(fileUriArrayList.get(i));
}
senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask(this);
senderDeviceAsyncTaskArray.execute(fileUriArrayList.toArray(new Uri[0]));
}
}
}
@ -559,9 +556,8 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
}
if (senderDeviceAsyncTaskArray != null) {
for (SenderDeviceAsyncTask task : senderDeviceAsyncTaskArray) {
task.cancel(true);
}
senderDeviceAsyncTaskArray.cancel(true);
} else if (receiverDeviceAsyncTask != null) {
receiverDeviceAsyncTask.cancel(true);
}

View File

@ -28,59 +28,74 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTra
* Once the handshake between the two connected devices has taked place, this async-task is used
* on the sender device to transfer the file to the receiver device at the FILE_TRANSFER_PORT port.
*
* It takes in the uri of a single file, and copies all the bytes from input stream of the file to
* the output stream of the receiver device. Also changes the status of the corresponding FileItem
* on the list of files for transfer.
* It takes in the uri of all the files to be shared. For each file uri, creates a new connection &
* copies all the bytes from input stream of the file to the output stream of the receiver device.
* Also changes the status of the corresponding FileItem on the list of files for transfer.
*
* A new task is created by the sender for every file to be transferred
* A single task is used by the sender for the entire transfer
*/
class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
class SenderDeviceAsyncTask extends AsyncTask<Uri, Integer, Boolean> {
private static final String TAG = "SenderDeviceAsyncTask";
private WeakReference<LocalFileTransferActivity> weakReferenceToActivity;
private int fileItemIndex;
private int fileItemIndex = -1;
public SenderDeviceAsyncTask(LocalFileTransferActivity localFileTransferActivity, int fileItemIndex) {
public SenderDeviceAsyncTask(LocalFileTransferActivity localFileTransferActivity) {
this.weakReferenceToActivity = new WeakReference<>(localFileTransferActivity);
this.fileItemIndex = fileItemIndex;
}
@Override
protected void onPreExecute() {
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
localFileTransferActivity.changeStatus(fileItemIndex, SENDING);
}
@Override
protected Boolean doInBackground(Uri... fileUris) {
Uri fileUri = fileUris[0]; // Uri of file to be transferred
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
ContentResolver contentResolver = localFileTransferActivity.getContentResolver();
try (Socket socket = new Socket(); // Represents the sender device
InputStream fileInputStream = contentResolver.openInputStream(fileUri)) {
Boolean result = true;
for(Uri fileUri : fileUris) { // Uri of file to be transferred
fileItemIndex++;
try (Socket socket = new Socket(); // Represents the sender device
InputStream fileInputStream = contentResolver.openInputStream(fileUri)) {
if (isCancelled()) {
result = false;
return result;
}
socket.bind(null);
String hostAddress = localFileTransferActivity.getFileReceiverDeviceAddress().getHostAddress();
socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000);
if (BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected());
publishProgress(fileItemIndex, SENDING);
OutputStream socketOutputStream = socket.getOutputStream();
copyToOutputStream(fileInputStream, socketOutputStream);
if (BuildConfig.DEBUG) Log.d(TAG, "Sender: Data written");
publishProgress(fileItemIndex, SENT);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
result = false;
showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_sending, getFileName(localFileTransferActivity.getFileUriArrayList().get(fileItemIndex))), Toast.LENGTH_SHORT);
publishProgress(fileItemIndex, ERROR);
if (isCancelled()) {
return false;
}
socket.bind(null);
String hostAddress = localFileTransferActivity.getFileReceiverDeviceAddress().getHostAddress();
socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000);
if (BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected());
OutputStream socketOutputStream = socket.getOutputStream();
copyToOutputStream(fileInputStream, socketOutputStream);
if (BuildConfig.DEBUG) Log.d(TAG, "Sender: Data written");
return true;
} catch (IOException e) {
Log.e(TAG, e.getMessage());
return false;
localFileTransferActivity.incrementTotalFilesSent();
}
return result;
}
@Override
protected void onProgressUpdate(Integer... values) {
int fileIndex = values[0];
int fileStatus = values[1];
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
localFileTransferActivity.changeStatus(fileIndex, fileStatus);
}
@Override protected void onCancelled() {
@ -90,15 +105,6 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
@Override
protected void onPostExecute(Boolean fileSendSuccessful) {
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
localFileTransferActivity.incrementTotalFilesSent();
if (fileSendSuccessful) { // Whether this task was successful in sending the file
localFileTransferActivity.changeStatus(fileItemIndex, SENT);
} else {
showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_sending,
getFileName(localFileTransferActivity.getFileUriArrayList().get(fileItemIndex))), Toast.LENGTH_SHORT);
localFileTransferActivity.changeStatus(fileItemIndex, ERROR);
}
if (localFileTransferActivity.allFilesSent()) {
showToast(localFileTransferActivity, R.string.file_transfer_complete,