首页 > 解决方案 > 将多张图片(近 100 张)从 Android 上传到 Amazon S3?

问题描述

我正在尝试将多个图像上传到亚马逊 s3 存储桶。我尝试上传的图像大小接近 300KB。我正在使用循环上传图像。但与ios相比,它需要更多时间。我正在使用以下代码将图像上传到 S3。

 val uploadObserver = transferUtility!!.upload(bucketname,
                    , "img_$timeStamp.jpg", File(fileUri.path!!),
                    md, CannedAccessControlList.PublicRead)

            uploadObserver.setTransferListener(object : TransferListener {
                override fun onStateChanged(id: Int, state: TransferState) {
                    if (TransferState.COMPLETED == state) {
                     
                    } else if (TransferState.FAILED == state) {
                  
                    }
                }

                override fun onProgressChanged(id: Int, bytesCurrent: Long, bytesTotal: Long) {
                  
                }

                override fun onError(id: Int, ex: Exception) {
                
                }
            })
        }

请帮助我,如何提高上传速度。

标签: androidamazon-web-serviceskotlinamazon-s3

解决方案


使用RxJavaRxAndroid,您可以一次执行多个异步任务。zip操作将所有任务绑定到一个任务中。您的案例的示例代码如下:

fun uploadTask(bucketname: String, timeStamp: Long, md: Any, uriList: List<Uri>) {
    
    val singles = mutableListOf<Single<String>>()
    uriList.forEach {
        singles.add(upload(bucketname, timeStamp, it, md).subscribeOn(Schedulers.io()))
    }
    val disposable = Single.zip(singles) {
        // If all request emits success response, then it will bind all emitted
        // object (in this example String) into an Array and you will get callback here.
        // You can change your final response here. In this can I am appending all strings
        // to a string.
        var finalString = ""
        it.forEach {  responseString ->
            finalString += responseString
        }
        finalString
    }
            .subscribe({
                // you will get final response here.
            }, {
                // If any one request failed and emits error all task will be stopped and error
                // will be thrown here.
                it.printStackTrace()
            })
    
}

upload()方法可以如下:

fun upload(bucketname: String, timeStamp: Long, fileUri: Uri, md: Any): Single<String> {
    return Single.create<String> { emitter ->  // You can change String to anything you want to emmit

        val uploadObserver = transferUtility!!.upload(bucketname,
                , "img_$timeStamp.jpg", File(fileUri.path!!),
                md, CannedAccessControlList.PublicRead)

        uploadObserver.setTransferListener(object : TransferListener {
            override fun onStateChanged(id: Int, state: TransferState) {
                if (TransferState.COMPLETED == state) {
                    emitter.onSuccess("COMPLETED")  // Emmit your object here
                } else if (TransferState.FAILED == state) {
                    emitter.onSuccess("FAILED")
                }
            }
    
            override fun onProgressChanged(id: Int, bytesCurrent: Long, bytesTotal: Long) {
            
            }
    
            override fun onError(id: Int, ex: Exception) {
                emitter.onError(ex)
            }
        })
    }
}

请记住,如果任何上传请求失败,所有其他任务都将停止。如果要继续,则必须onErrorResumeNext()在这种情况下使用运算符。


推荐阅读