如何/何时释放recyclerView中viewHolder获取的资源?

How / when to release the resources acquired by viewHolder in a recyclerView?

为了简单起见,我有一个 recyclerView,它有 viewHolders 持有 MediaPlayer 实例。当用户关闭activity时,我想释放MediaPlayer实例获取的资源。但与 onCreateViewHolder 不同的是,我找不到任何 onDestroyViewHolder 方法。我的 viewHolder 实现如下所示:

class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    private val mMediaPlayer: MediaPlayer? = null
    
    internal fun onBind(model: Model) {
        if(model.contentType == "Audio") {
            mMediaPlayer = MediaPlayer()
            mMediaPlayer.setOnPreparedListener(mPreparedListener);
            mMediaPlayer.setOnCompletionListener(mCompletionListener);
            mMediaPlayer.setDataSource(mContext, uri, null)
            mMediaPlayer.prepareAsync()
            // do other stuff

        } else if(mMediaPlayer != null) {
            mMediaPlayer.reset()
            mMediaPlayer.release()
            mMediaPlayer = null
        }
    }
}

我知道适配器 class 有 onViewDetachedFromWindow 方法。但我不确定这是否适合这里。有人可以告诉我解决方案吗?

您应该在您的 viewHolder 中创建 releaseResources 的方法并从 onViewRecycled 调用它,它在您的回收器适配器中被覆盖

    override fun onViewRecycled(holder: MediaViewHolder) {
        super.onViewRecycled(holder)
        val videoItem = mediaItems.getOrNull(holder.bindingAdapterPosition)
        holder.releasePlayer(videoItem)
    }

为了在每次片段进入停止状态时调用此方法,您应该将 recyclerview 适配器设置为 null

  override fun onStop() {
        super.onStop()
        currentPage = binding.pager.currentItem
        binding.pager.adapter = null
  }

这将导致在所有 viewHolder 上调用 onViewRecycled

并且您应该在 onStart()

中将适配器设置回 recyclerview
override fun onStart() {
    super.onStart()
    if (binding.pager.adapter == null) {
        binding.pager.adapter = adapter
        binding.pager.setCurrentItem(currentPage, false)
    }
}

这个例子在 ViewPager2 上,但它也适用于 RecyclerView。