[demo-compose] Add Activity lifecycle methods

Take care of releasing the player and re-initialising when returning to the app to prevent memory leaks.

Instead of overriding onStart, onPause, onResume, onStop - use Lifecycle*Effects for a more native compose cleanup. Requires a higher version of the lifecycle library.

PiperOrigin-RevId: 712542884
This commit is contained in:
jbibik 2025-01-06 08:47:01 -08:00 committed by Copybara-Service
parent d8333b37cf
commit ff80ab220f
3 changed files with 33 additions and 2 deletions

View file

@ -46,7 +46,7 @@ project.ext {
androidxConstraintLayoutVersion = '2.1.4'
androidxCoreVersion = '1.8.0'
androidxExifInterfaceVersion = '1.3.6'
androidxLifecycleVersion = '2.6.0'
androidxLifecycleVersion = '2.8.7'
androidxMediaVersion = '1.7.0'
androidxRecyclerViewVersion = '1.3.0'
androidxMaterialVersion = '1.8.0'

View file

@ -74,6 +74,7 @@ dependencies {
implementation 'androidx.compose.material3:material3'
implementation 'androidx.compose.material:material-icons-extended'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.lifecycle:lifecycle-runtime-compose:' + androidxLifecycleVersion
implementation 'com.google.android.material:material:' + androidxMaterialVersion
implementation project(modulePrefix + 'lib-exoplayer')

View file

@ -16,6 +16,7 @@
package androidx.media3.demo.compose
import android.content.Context
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@ -34,6 +35,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.compose.LifecycleResumeEffect
import androidx.lifecycle.compose.LifecycleStartEffect
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.demo.compose.buttons.ExtraControls
@ -57,7 +60,34 @@ class MainActivity : ComponentActivity() {
fun ComposeDemoApp(modifier: Modifier = Modifier) {
val context = LocalContext.current
var player by remember { mutableStateOf<Player?>(null) }
player = initializePlayer(context)
// See the following resources
// https://developer.android.com/topic/libraries/architecture/lifecycle#onStop-and-savedState
// https://developer.android.com/develop/ui/views/layout/support-multi-window-mode#multi-window_mode_configuration
// https://developer.android.com/develop/ui/compose/layouts/adaptive/support-multi-window-mode#android_9
if (Build.VERSION.SDK_INT > 23) {
// Initialize/release in onStart()/onStop() only because in a multi-window environment multiple
// apps can be visible at the same time. The apps that are out-of-focus are paused, but video
// playback should continue.
LifecycleStartEffect(Unit) {
player = initializePlayer(context)
onStopOrDispose {
player?.apply { release() }
player = null
}
}
} else {
// Call to onStop() is not guaranteed, hence we release the Player in onPause() instead
LifecycleResumeEffect(Unit) {
player = initializePlayer(context)
onPauseOrDispose {
player?.apply { release() }
player = null
}
}
}
player?.let { MediaPlayerScreen(player = it, modifier = modifier.fillMaxSize()) }
}