如何/何时释放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。
为了简单起见,我有一个 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()
中将适配器设置回 recyclerviewoverride fun onStart() {
super.onStart()
if (binding.pager.adapter == null) {
binding.pager.adapter = adapter
binding.pager.setCurrentItem(currentPage, false)
}
}
这个例子在 ViewPager2 上,但它也适用于 RecyclerView。