Kotlin协程的正确使用方法

时间:2020-06-24 06:36:38

标签: android android-layout kotlin kotlin-coroutines

我正在使用kotlin coroutinescope从视频uri加载缩略图,并以线性布局添加带有该位图的imageview。

当前,在加载所有缩略图之后,我将添加到linearlayout中。谁能建议我一步一步地添加到线性布局中?

private fun loadThumbnails(uri: Uri) {
    val metaDataSource = MediaMetadataRetriever()
    metaDataSource.setDataSource(context, uri)

    val videoLength = (metaDataSource.extractMetadata(
            MediaMetadataRetriever.METADATA_KEY_DURATION).toInt() * 1000).toLong()

    val thumbnailCount = 8

    val interval = videoLength / thumbnailCount

    var listOfImage: ArrayList<Bitmap?> = ArrayList()

    for (i in 0 until thumbnailCount - 1) {

        try {
            var bitmap: Bitmap? = null
            val job = CoroutineScope(Dispatchers.IO).launch {
                val frameTime = i * interval
                bitmap = metaDataSource.getFrameAtTime(frameTime, MediaMetadataRetriever.OPTION_CLOSEST)

                bitmap?.let {
                    val targetWidth: Int
                    val targetHeight: Int
                    if (it.height > it.width) {
                        targetHeight = frameDimension
                        val percentage = frameDimension.toFloat() / it.height
                        targetWidth = (it.width * percentage).toInt()
                    } else {
                        targetWidth = frameDimension
                        val percentage = frameDimension.toFloat() / it.width
                        targetHeight = (it.height * percentage).toInt()
                    }
                    bitmap = Bitmap.createScaledBitmap(it, targetWidth, targetHeight, false)
                }
                listOfImage.add(bitmap)
                metaDataSource.release()
            }

        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    listOfImage.forEach {
        container_thumbnails.addView(ThumbnailView(context).apply { setImageBitmap(it) })
    }

}

1 个答案:

答案 0 :(得分:1)

请尝试下一种方法:

val job = CoroutineScope(Dispatchers.Main).launch {
    val frameTime = i * interval
    val bitmap = loadBitmap(frameTime) // loads bitmap asynchronously using withContext(Dispatchers.IO)

    // ... use bitmap to set into a view
}

suspend fun loadBitmap(frameTime: Int): Bitmap? = withContext(Dispatchers.IO) {
    bitmap = metaDataSource.getFrameAtTime(frameTime, MediaMetadataRetriever.OPTION_CLOSEST)

    bitmap?.let {
        val targetWidth: Int
        val targetHeight: Int
        if (it.height > it.width) {
             targetHeight = frameDimension
             val percentage = frameDimension.toFloat() / it.height
             targetWidth = (it.width * percentage).toInt()
        } else {
             targetWidth = frameDimension
             val percentage = frameDimension.toFloat() / it.width
             targetHeight = (it.height * percentage).toInt()
        }
        Bitmap.createScaledBitmap(it, targetWidth, targetHeight, false)
    }
}