To be simple, I have a recyclerView which has viewHolders holding MediaPlayer instances. When users close that activity, I want to release the resources aquired by MediaPlayer instance. But unlike onCreateViewHolder, I couldn't find any onDestroyViewHolder methods. My viewHolder implementation looks like this:
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
}
}
}
I know the Adapter class has onViewDetachedFromWindow method. But I am not sure whether that can fit here. Can someone tell me a solution for this?
You should create method to releaseResources in your viewHolder and call it from onViewRecycled which is overriden in your recycler adapter
override fun onViewRecycled(holder: MediaViewHolder) {
super.onViewRecycled(holder)
val videoItem = mediaItems.getOrNull(holder.bindingAdapterPosition)
holder.releasePlayer(videoItem)
}
in order to get this method called each time your fragment goes to stop state you should set recyclerview adapter to null
override fun onStop() {
super.onStop()
currentPage = binding.pager.currentItem
binding.pager.adapter = null
}
this will cause onViewRecycled to be called on all viewHolders
and you should set adapter back on recyclerview in onStart()
override fun onStart() {
super.onStart()
if (binding.pager.adapter == null) {
binding.pager.adapter = adapter
binding.pager.setCurrentItem(currentPage, false)
}
}
this example is on ViewPager2 but this works with RecyclerView also.