Reputation: 61
I am using TransferUtility for uploading image on Amazon S3 server. I am trying to upload 3 images one by one but it is uploading parallely. I want to upload the images one by one. How should I do it? I am using this below code for uploading:
private void uploadToAWS(TransferUtility transferUtility,final ArrayList<File> imageFileArrayList){
final ArrayList<String> uploadedFileArrayList = new ArrayList<>();
final ArrayList<String> failedFileArrayList = new ArrayList<>();
for(int i = 0; i < imageFileArrayList.size(); i++) {
final File file = imageFileArrayList.get(i);
final TransferObserver observer = transferUtility.upload(
Constants.S3_BUCKET_NAME, /* The bucket to upload to */
"Test_Images" + file.getAbsolutePath(), /* The key for the uploaded object */
file /* The file where the data to upload exists */
);
observer.setTransferListener(new TransferListener() {
@Override
public void onStateChanged(int id, TransferState state) {
System.out.println("Id:- " + id);
if (state == TransferState.COMPLETED) {
uploadedFileArrayList.add(observer.getAbsoluteFilePath());
} else if (state == TransferState.FAILED) {
failedFileArrayList.add(file.getAbsolutePath());
}
}
@Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
int percent = (int) ((bytesCurrent * 100) / bytesTotal);
System.out.println("percent:- " + percent);
}
@Override
public void onError(int id, Exception ex) {
ex.printStackTrace();
System.out.println("Id:- " + id + " in exception");
}
});
}
}
This function I am calling in Asynctask.
@Override
protected Void doInBackground(Void... params) {
AmazonS3 amazonS3 = new AmazonS3Client(getAWSCredentials());
TransferUtility transferUtility = new TransferUtility(amazonS3, context);
uploadToAWS(transferUtility, imageFileArrayList);
return null;
}
Please help.
Upvotes: 3
Views: 163
Reputation: 3331
OK so here is the issue: You are calling transferUtility.upload()
from a loop in uploadToAWS()
. Now you call for the first file upload but without waiting for completion (since you've put it in a loop) you iterate through the loop and call for the next file to upload, so on and so forth...
Now to avoid this, all you need to do is wait for the TransferState.COMPLETED
event callback and once you have it, you should call the next file upload (via another call to transferUtility.upload()
).
Also you might wanna add some code for retries in case the upload fails in TransferState.FAILED
callback.
So your code becomes roughly like so:
private void uploadToAWS(TransferUtility transferUtility,final ArrayList<File> imageFileArrayList) {
final File file = imageFileArrayList.get(i);
final TransferObserver observer = transferUtility.upload(
Constants.S3_BUCKET_NAME, /* The bucket to upload to */
"Test_Images" + file.getAbsolutePath(), /* The key for the uploaded object */
file /* The file where the data to upload exists */
);
observer.setTransferListener(new TransferListener() {
@Override
public void onStateChanged(int id, TransferState state) {
System.out.println("Id:- " + id);
if (state == TransferState.COMPLETED) {
uploadedFileArrayList.add(observer.getAbsoluteFilePath());
failedFileArrayList.remove(file.getAbsolutePath());
i++;
uploadToAWS(transferUtility, imageFileArrayList);
} else if (state == TransferState.FAILED) {
failedFileArrayList.add(file.getAbsolutePath());
uploadToAWS(transferUtility, imageFileArrayList);
}
}
@Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
int percent = (int) ((bytesCurrent * 100) / bytesTotal);
System.out.println("percent:- " + percent);
}
@Override
public void onError(int id, Exception ex) {
failedFileArrayList.add(file.getAbsolutePath());
ex.printStackTrace();
System.out.println("Id:- " + id + " in exception");
}
});
}
}
This is very rough implementation of what your code might look like. You may want to change your entire flow which is of course better.
Upvotes: 1