I'm building an Android app which uses AWS Amplify to list and download files from S3.
The sample code shows downloading is asynchronous:
Amplify.Storage.downloadFile()
"ExampleKey",
new File(getApplicationContext().getFilesDir() + "/download.txt"),
result -> Log.i("MyAmplifyApp", "Successfully downloaded: " + result.getFile().getName()),
error -> Log.e("MyAmplifyApp", "Download Failure", error)
);
I wish to download the (possibly many) files in a background thread, and notify the main thread after all files have been downloaded (or an error occurred). Questions:
What is the best way to achieve this functionality?
P.S.
I've tried the RxAmplify, which exposes RxJava Observables on which I can call blockingSubscribe()
. However, the bindings are very new, and I've encountered some app-crashing uncaught exceptions using it.
downloadFile()
will perform its work on a background thread. Just use one of the standard approaches to go back onto the main thread, from the callback:
Handler handler = new Handler(context.getMainLooper());
File file = new File(context.getFilesDir() + "/download.txt");
Amplify.Storage.downloadFile(
"ExampleKey", file,
result -> {
handler.post(() -> {
Log.i("MyAmplifyApp", "Successfully downloaded: " + result.getFile().getName());
});
},
error -> Log.e("MyAmplifyApp", "Download Failure", error)
);
But personally, I would use the Rx Bindings. The official documentation includes snippets for the Rx API. Here's a more tailored example:
File file = new File(context.getFilesDir() + "/download.txt");
RxAmplify.Storage.downloadFile("ExampleKey", file)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
Log.i("RxExample", "Download OK.");
}, failure -> {
Log.e("RxExample", "Failed.", failure);
});
Build a collection of Single
s by calling RxAmplify.Storage.downloadFile("key", local)
. Then, use Single.mergeArray(...)
to combine them all. Subscribe to that, in the same way as above.
RxStorageCategoryBehavior storage = RxAmplify.Storage;
Single
.mergeArray(
storage.downloadFile("one", localOne)
.observeResult(),
storage.downloadFile("two", localTwo)
.observeResult()
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(/* args ... */);
You mention that you encountered an unexpected exception. If so, please file a bug here, and I will fix it.