diff --git a/constants.gradle b/constants.gradle index 3cf29f424d..c81738a0ec 100644 --- a/constants.gradle +++ b/constants.gradle @@ -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' diff --git a/demos/compose/build.gradle b/demos/compose/build.gradle index e76e45a69b..5897c3095e 100644 --- a/demos/compose/build.gradle +++ b/demos/compose/build.gradle @@ -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') diff --git a/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt b/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt index c50f700ed4..25aac48702 100644 --- a/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt +++ b/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt @@ -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(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()) } }