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) { if (fileItem.getFileStatus() == SENDING) {
holder.statusImage.setVisibility(View.GONE); holder.statusImage.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.VISIBLE); holder.progressBar.setVisibility(View.VISIBLE);
} else if (fileItem.getFileStatus() } else if (fileItem.getFileStatus() != TO_BE_SENT) {
!= TO_BE_SENT) { // Icon for TO_BE_SENT is assigned by default in the item layout // Icon for TO_BE_SENT is assigned by default in the item layout
holder.progressBar.setVisibility(View.GONE); holder.progressBar.setVisibility(View.GONE);
switch (fileItem.getFileStatus()) { 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.text_view_empty_peer_list) TextView textViewPeerDevices;
@BindView(R.id.recycler_view_transfer_files) RecyclerView filesRecyclerView; @BindView(R.id.recycler_view_transfer_files) RecyclerView filesRecyclerView;
private ArrayList<Uri> fileUriArrayList; // For sender device, stores uris of the files 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 public boolean isFileSender = false; // Whether the device is the file sender or not
public @NonNull WifiDirectManager wifiDirectManager = new WifiDirectManager(this); public @NonNull WifiDirectManager wifiDirectManager = new WifiDirectManager(this);
@ -104,7 +104,7 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
private boolean fileTransferStarted = false; private boolean fileTransferStarted = false;
private PeerGroupHandshakeAsyncTask peerGroupHandshakeAsyncTask; private PeerGroupHandshakeAsyncTask peerGroupHandshakeAsyncTask;
private SenderDeviceAsyncTask[] senderDeviceAsyncTaskArray; private SenderDeviceAsyncTask senderDeviceAsyncTaskArray;
private ReceiverDeviceAsyncTask receiverDeviceAsyncTask; private ReceiverDeviceAsyncTask receiverDeviceAsyncTask;
@Override @Override
@ -295,11 +295,8 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
showToast(this, R.string.preparing_files, Toast.LENGTH_LONG); showToast(this, R.string.preparing_files, Toast.LENGTH_LONG);
for (int i = 0; i < 20000000; i++) ; for (int i = 0; i < 20000000; i++) ;
senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask[totalFilesForTransfer]; senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask(this);
for (int i = 0; i < totalFilesForTransfer; i++) { senderDeviceAsyncTaskArray.execute(fileUriArrayList.toArray(new Uri[0]));
senderDeviceAsyncTaskArray[i] = new SenderDeviceAsyncTask(this, i);
senderDeviceAsyncTaskArray[i].execute(fileUriArrayList.get(i));
}
} }
} }
} }
@ -559,9 +556,8 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
} }
if (senderDeviceAsyncTaskArray != null) { if (senderDeviceAsyncTaskArray != null) {
for (SenderDeviceAsyncTask task : senderDeviceAsyncTaskArray) { senderDeviceAsyncTaskArray.cancel(true);
task.cancel(true);
}
} else if (receiverDeviceAsyncTask != null) { } else if (receiverDeviceAsyncTask != null) {
receiverDeviceAsyncTask.cancel(true); 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 * 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. * 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 * It takes in the uri of all the files to be shared. For each file uri, creates a new connection &
* the output stream of the receiver device. Also changes the status of the corresponding FileItem * copies all the bytes from input stream of the file to the output stream of the receiver device.
* on the list of files for transfer. * 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 static final String TAG = "SenderDeviceAsyncTask";
private WeakReference<LocalFileTransferActivity> weakReferenceToActivity; 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.weakReferenceToActivity = new WeakReference<>(localFileTransferActivity);
this.fileItemIndex = fileItemIndex;
}
@Override
protected void onPreExecute() {
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
localFileTransferActivity.changeStatus(fileItemIndex, SENDING);
} }
@Override @Override
protected Boolean doInBackground(Uri... fileUris) { protected Boolean doInBackground(Uri... fileUris) {
Uri fileUri = fileUris[0]; // Uri of file to be transferred
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get(); final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
ContentResolver contentResolver = localFileTransferActivity.getContentResolver(); ContentResolver contentResolver = localFileTransferActivity.getContentResolver();
try (Socket socket = new Socket(); // Represents the sender device Boolean result = true;
InputStream fileInputStream = contentResolver.openInputStream(fileUri)) {
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); localFileTransferActivity.incrementTotalFilesSent();
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;
} }
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() { @Override protected void onCancelled() {
@ -90,15 +105,6 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
@Override @Override
protected void onPostExecute(Boolean fileSendSuccessful) { protected void onPostExecute(Boolean fileSendSuccessful) {
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get(); 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()) { if (localFileTransferActivity.allFilesSent()) {
showToast(localFileTransferActivity, R.string.file_transfer_complete, showToast(localFileTransferActivity, R.string.file_transfer_complete,