Upload multiple images(nearly 100) from Android to Amazon S3?

吃可爱长大的小学妹 提交于 2021-02-11 13:36:28

问题


I am trying to upload multiple image to amazon s3 bucket. The size of the images which i am trying to upload is nearly 300KB each. I am using loop to upload the images. But it's taking more time compared to ios. I am using the below code to upload the images to 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) {
                
                }
            })
        }

Please help me, how to increase the speed of upload.


回答1:


Using RxJava and RxAndroid you can do multiple async task at a time. zip operate binds all task into one task. Sample code for your case is as following:

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

And upload() method can be as following:

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

Just keep in mind, if any upload request is failed, all other task will be stopped. If you want to continue you have to use onErrorResumeNext() operator in that case.



来源:https://stackoverflow.com/questions/63026703/upload-multiple-imagesnearly-100-from-android-to-amazon-s3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!