我需要下载多张图片,在所有下载完成后(在主线程之外),执行活动中的其他操作。
我目前正在使用Glide进行下载,如下所示:
ImageDownloader.kt
class ImageDownloader {
fun downloadPack(context: Context, path: String, pack: PackModel) {
for (image: ImageModel in pack.images) {
Glide.with(context)
.asBitmap()
.load(image.imageFileUrl)
.listener(object : RequestListener<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
return false
}
override fun onResourceReady(bitmap: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
saveImage(path, pack.id, image.imageFileName, bitmap!!)
return true
}
}).submit()
}
}
private fun saveImage(path: String, id: String, fileName: String, bitmap: Bitmap) {
val dir = File(path + id)
if (!dir.exists()) dir.mkdirs()
val file = File(dir, fileName)
val out = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.PNG, 75, out)
out.flush()
out.close()
// to check the download progress for each image in logcat
println("done: $fileName")
}
}
在这个活动中,我使用以下方式在CoroutineScope中调用此方法:
PackActivity.kt
class PackActivity: AppCompatActivity() {
private lateinit var bind: ActivityPackBinding
private lateinit var path: String
private lateinit var pack: PackModel
// other basic codes
override fun onCreate(savedInstanceState: Bundle?) {
// other basic codes
path = "$filesDir/images_asset/"
pack = intent.getParcelableExtra(PACK_DATA)!!
bind.buttonDownload.setOnClickListener {
downloadPack()
}
}
private fun downloadPack() {
CoroutineScope(Dispatchers.IO).launch {
val async = async {
ImageDownloader().downloadPack(applicationContext, path, pack)
}
val result = async.await()
withContext(Dispatchers.Main) {
result.apply {
println("finished")
// other things todo
}
}
}
}
}
在PackActivity.kt中下载所有图片后,我想继续进行其他操作,但实际上,在使用println("finished")并检查logcat后,代码甚至在第一次下载开始之前就开始执行了...
一些信息:
PackModel
和ImageModel
是我的数据类,其中PackModel
具有每个包的ID及其ImageModel
列表,而ImageModel
则具有ImageFileName
和ImageFileUrl
。 所有数据都来自Web请求。
我希望将图像保存在文件夹data/data/AppPackageName/files/images_asset/PackID/...中,并且通过我所做的测试,我无法使用DownloadManager直接将图像定向到应用程序的内部文件夹,因此我正在使用Glide。
suspend fun
,只需从launch
块中调用它并删除您的async-await
,因为它完全没有作用。async { suspendFun() }.await()
与suspendFun()
具有完全相同的语义,但引入了不必要的开销。 - Marko Topolnikasync
await
的倾向是受到 JavaScript 影响的结果。 - George Leung