问题
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