解决RecyclerView获取视频某一帧作为封面时卡顿

321 阅读1分钟

起因

项目里写了一个列表展示视频,每个item都有一张图片,这张图片的来源是视频的最后一帧。结果发现切换fragment的时候只有这个fragment会卡住几秒。

找原因发现是因为在ViewHolder里面获取视频最后一帧这个方法导致的卡顿,所以应该要异步加载

我当时尝试直接直接在ViewHolder里面开了协程,但是发现没有效果。

解决方案

写了一个ImageLoader去异步处理加载图片。

class ImageLoader(root: View) {  
    private lateinit var mImageView: ImageView  
    private lateinit var mUrl: String  
  
 private val mHandler: Handler = object : Handler(Looper.getMainLooper()){  
    override fun handleMessage(msg: Message) {  
      super.handleMessage(msg)  
      // 这里写视图绑定的逻辑
      val requestOptions = RequestOptions.bitmapTransform(RoundedCorners(10)) 
      GlideApp.with(root)  
        .load(msg.obj as Bitmap)  
        .apply(requestOptions)  
        .into(mImageView)  
    }  
 }  
  
 @RequiresApi(Build.VERSION_CODES.P)  
 fun showImageByThread(imageView: ImageView, url: String){  
    mImageView = imageView  
    mUrl = url  
  
    CoroutineScope(Dispatchers.Default).launch {  
        var bitmap = MediaUtil.getLastTimeFrame(mUrl) // 获取视频最后一帧
        var message = Message.obtain()  
        bitmap?.let {  
            message.obj = bitmap  
            mHandler.sendMessage(message)  
        }  
    }  
 }     
}

在Recycler的ViewHolder中直接调用就行。

binding.vedioIconImage是item中的图片,recordPath是视频路径。

ImageLoader(binding.root).showImageByThread(binding.videoIconImage, recordPath)