【问题标题】:Downloading multiple files using AWS Amplify for Android使用适用于 Android 的 AWS Amplify 下载多个文件
【发布时间】:2020-09-21 15:00:11
【问题描述】:

我正在构建一个 Android 应用,它使用 AWS Amplify 从 S3 列出和下载文件。

示例代码显示下载是异步的:

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)
);

我希望在后台线程中下载(可能很多)文件,并在所有文件下载完毕(或发生错误)后通知主线程。问题:

实现此功能的最佳方法是什么?

附: 我试过RxAmplify,它暴露了RxJava Observables,我可以在上面调用blockingSubscribe()。但是,绑定是非常新的,使用它时我遇到了一些应用程序崩溃未捕获的异常。

【问题讨论】:

    标签: android amazon-web-services aws-amplify


    【解决方案1】:

    使用香草放大

    downloadFile() 将在后台线程上执行其工作。只需使用 standard approaches 之一从回调返回主线程:

    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)
    );
    

    使用 Rx 绑定

    但就个人而言,我会使用 Rx 绑定。 The official documentation 包括用于 Rx API 的 sn-ps。这是一个更量身定制的示例:

    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);
        });
    

    并行运行多个下载

    通过调用RxAmplify.Storage.downloadFile("key", local) 构建Singles 的集合。然后,使用Single.mergeArray(...) 将它们全部组合起来。订阅它,方法同上。

    RxStorageCategoryBehavior storage = RxAmplify.Storage;
    Single
        .mergeArray(
            storage.downloadFile("one", localOne)
                .observeResult(),
            storage.downloadFile("two", localTwo)
                .observeResult()
        )
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(/* args ... */);
    

    报告错误

    您提到您遇到了意外的异常。如果是这样,请提交错误here,我会修复它。

    【讨论】:

    • 谢谢。按原样使用您的示例,我得到了mergeArray() 的错误:“原因:不存在类型变量 T 的实例,因此 RxProgressAwareSingleOperation 符合 SingleSource extends T>”。我想我应该将observeResult() 添加到每个downloadFile()
    • + 我想知道在这种情况下如何同时观察结果和进展......
    • 啊,是的,必须在 mergeArray(...) 内的调用中添加 .observeResult()。更新了帖子。要同时观察进度,请创建操作集合。然后,通过合并各种.observeProgress(),形成一个Observable
    • 谢谢@Jameson。如何合并未知数量的单曲?即之前对桶的list()操作的结果?
    • @bavaza 这是一个起点。您可能想要创建自己的Download 模型,将密钥、文件和操作都保存在一个地方。否则,您无法判断进度是针对哪个下载的。 gist.github.com/jamesonwilliams/…
    猜你喜欢
    • 2020-11-08
    • 1970-01-01
    • 2021-06-18
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 2012-05-21
    相关资源
    最近更新 更多