Skip to content

Commit 57d0721

Browse files
tianyificbaker
authored andcommitted
Resolve the memory leaks in demo short-form app
Issue: #1839 PiperOrigin-RevId: 696080063 (cherry picked from commit c3d4722)
1 parent a46716c commit 57d0721

File tree

3 files changed

+29
-19
lines changed

3 files changed

+29
-19
lines changed

RELEASENOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
per sample.
88
* Fix playback hanging on DASH multi-period streams when CEA-608 subtitles
99
are enabled ([#1863](https://github.com/androidx/media/issues/1863)).
10+
* Demo app
11+
* Resolve the memory leaks in demo short-form app
12+
([#1839](https://github.com/androidx/media/issues/1839)).
1013

1114
## 1.5
1215

demos/shortform/src/main/java/androidx/media3/demo/shortform/viewpager/ViewPagerActivity.kt

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import androidx.viewpager2.widget.ViewPager2
2525

2626
class ViewPagerActivity : AppCompatActivity() {
2727
private lateinit var viewPagerView: ViewPager2
28-
private lateinit var adapter: ViewPagerMediaAdapter
28+
private lateinit var onPageChangeCallback: ViewPager2.OnPageChangeCallback
2929
private var numberOfPlayers = 3
3030
private var mediaItemDatabase = MediaItemDatabase()
3131

@@ -40,23 +40,24 @@ class ViewPagerActivity : AppCompatActivity() {
4040
Log.d(TAG, "Using a pool of $numberOfPlayers players")
4141
viewPagerView = findViewById(R.id.viewPager)
4242
viewPagerView.offscreenPageLimit = 1
43-
viewPagerView.registerOnPageChangeCallback(
44-
object : ViewPager2.OnPageChangeCallback() {
45-
override fun onPageSelected(position: Int) {
46-
adapter.onPageSelected(position)
47-
}
48-
}
49-
)
5043
}
5144

5245
override fun onStart() {
5346
super.onStart()
54-
adapter = ViewPagerMediaAdapter(mediaItemDatabase, numberOfPlayers, this)
47+
val adapter = ViewPagerMediaAdapter(mediaItemDatabase, numberOfPlayers, applicationContext)
5548
viewPagerView.adapter = adapter
49+
onPageChangeCallback =
50+
object : ViewPager2.OnPageChangeCallback() {
51+
override fun onPageSelected(position: Int) {
52+
adapter.onPageSelected(position)
53+
}
54+
}
55+
viewPagerView.registerOnPageChangeCallback(onPageChangeCallback)
5656
}
5757

5858
override fun onStop() {
59-
adapter.onDestroy()
59+
viewPagerView.unregisterOnPageChangeCallback(onPageChangeCallback)
60+
viewPagerView.adapter = null
6061
super.onStop()
6162
}
6263
}

demos/shortform/src/main/java/androidx/media3/demo/shortform/viewpager/ViewPagerMediaAdapter.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ViewPagerMediaAdapter(
4343
private val currentMediaItemsAndIndexes: ArrayDeque<Pair<MediaItem, Int>> = ArrayDeque()
4444
private var playerPool: PlayerPool
4545
private val holderMap: MutableMap<Int, ViewPagerMediaHolder>
46-
private var currentPlayingIndex: Int = C.INDEX_UNSET
46+
private val preloadControl: DefaultPreloadControl
4747

4848
companion object {
4949
private const val TAG = "ViewPagerMediaAdapter"
@@ -65,8 +65,10 @@ class ViewPagerMediaAdapter(
6565
)
6666
.setPrioritizeTimeOverSizeThresholds(true)
6767
.build()
68+
preloadControl = DefaultPreloadControl()
6869
val preloadManagerBuilder =
69-
DefaultPreloadManager.Builder(context, DefaultPreloadControl()).setLoadControl(loadControl)
70+
DefaultPreloadManager.Builder(context.applicationContext, preloadControl)
71+
.setLoadControl(loadControl)
7072
playerPool = PlayerPool(numberOfPlayers, preloadManagerBuilder)
7173
holderMap = mutableMapOf()
7274
preloadManager = preloadManagerBuilder.build()
@@ -76,6 +78,13 @@ class ViewPagerMediaAdapter(
7678
preloadManager.invalidate()
7779
}
7880

81+
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
82+
playerPool.destroyPlayers()
83+
preloadManager.release()
84+
holderMap.clear()
85+
super.onDetachedFromRecyclerView(recyclerView)
86+
}
87+
7988
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewPagerMediaHolder {
8089
val view =
8190
LayoutInflater.from(parent.context).inflate(R.layout.media_item_view_pager, parent, false)
@@ -128,14 +137,9 @@ class ViewPagerMediaAdapter(
128137
return Int.MAX_VALUE
129138
}
130139

131-
fun onDestroy() {
132-
playerPool.destroyPlayers()
133-
preloadManager.release()
134-
}
135-
136140
fun onPageSelected(position: Int) {
137-
currentPlayingIndex = position
138141
holderMap[position]?.playIfPossible()
142+
preloadControl.currentPlayingIndex = position
139143
preloadManager.setCurrentPlayingIndex(position)
140144
preloadManager.invalidate()
141145
}
@@ -168,7 +172,9 @@ class ViewPagerMediaAdapter(
168172
preloadManager.remove(itemAndIndex.first)
169173
}
170174

171-
inner class DefaultPreloadControl : TargetPreloadStatusControl<Int> {
175+
inner class DefaultPreloadControl(var currentPlayingIndex: Int = C.INDEX_UNSET) :
176+
TargetPreloadStatusControl<Int> {
177+
172178
override fun getTargetPreloadStatus(rankingData: Int): DefaultPreloadManager.Status? {
173179
if (abs(rankingData - currentPlayingIndex) == 2) {
174180
return DefaultPreloadManager.Status(STAGE_LOADED_FOR_DURATION_MS, 500L)

0 commit comments

Comments
 (0)