Question

I'm using the Amazon AWS S3 SDK for video and data uploads in Android, and I've got it working fine for 'normal' (i.e., non Multipart) uploads, running in an AsyncTask so as not hold up the UI.

If I allow the user to cancel the upload (for whatever reason), the progress bar disappears, but the AsyncTask seems to hang up until the upload completes. I've tried killing it with the usual methods, but I think the problem is due to the AWS call continuing with the upload, even though I've tried to kill the AsyncTask.

Having trawled around SO and the AWS forums, what I think I need in order to be able to cancel an in-progress upload, is a MultiPart upload, to allow me to abort the upload AsyncTask between part-uploads. Trouble is, I can't find any examples of how to do this in Android, or samples of code in the samples-bundle that comes with the AWS SDK (that I can find).

Does anyone know of a tutorial, or a sample project that I can get ideas from, to get a Multipart upload working? Do I need to use TransferManager to do this?

Many thanks in advance!

Was it helpful?

Solution

After much testing, I've concluded that the AWS API doesn't allow you stop an upload that's in the middle of a transfer.

The abortMultipartUploads() and abortMultipartUpload() methods that are available when using the Low-Level and High-Level (TransferManager) uploads, don't do what their name suggests: what these methods do, is to inhibit any further parts of the upload from being started, but only when some of the parts have already completed uploading. They don't actually abort an upload in the middle of its transfer.

Two methods are provided which are supposed to stop an upload immediately ( shutdown() and shutdownNow() ), but these methods don't seem to have any effect whatsoever on the an in-progress transfer once it's been started.

If you use the Low-Level multipart upload methods, then you can pause and resume an upload, but there's no actual way to stop it. Pausing only stops the upload sequence when the last part has finished transferring, but this transfer is a minimum of 5Mb, so if you're on a slow data connection, this 5Mb could take a while to actually pause.

I suspect that the API provided by AWS is designed primarily for professional server applications for corporate users and is only paying lip-service to mobile application use. It may be a deliberate step by AWS in not allowing a transfer to be halted.

Whatever the case, I have found only one way to stop a transfer once it's been started. I expect there to be protests from some quarters of SO about using this method, but until AWS provide a better API for Android, I'm stuck with it:

I'm using TransferManager (Android example here) to start an upload, and then tracking progress using a thread, to update a progress bar via a handler.

At the point where the decision is taken to cancel, I shutdown all of my running threads and the progress bar. TransferManager is oblivious to all of this and carries on with the transfer in it's own thread that you can't stop directly, so the next step is to call:

finish();

followed by:

System.exit(0);

or:

Process.killProcess(Process.myPid());

This causes Android to dump back to the calling Activity, and forces a clean up of all resources currently in use. Crucially, it pulls the plug on the resources used by TransferManager, thus causing the transfer to stop immediately. If you think that any parts of an upload have already completed, you might still need to call abortMultipartUploads() or abortMultipartUpload() on that same bucket in order to get AWS to clean up partial uploads, otherwise you might still be paying for that upload part.

It's not pretty and I'd prefer to use a proper shutdown method, but until AWS provide a method to do just that, this is the only way I've found of calling a full halt to an in-progress transfer.

Hope this helps someone faced with the same problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top