mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
[ui-compose] Fix PlayerSurface's use of Player
When `PlayerSurface` composable gets a new `Player` object, it should initialise a new Android(Embedded)External Surface with it. However, the lambdas used for that are remembered with the reference to the old Player, even if it has been null'd and released properly. Android(Embedded)ExternalSurface is an interop - `AndroidView` wrapping `SurfaceView` and `TextureView` under the hood. It uses the `onInit` lambda in its factory to create the View and reuses it on later recompositions, making it a longer-lived object than our Player. `RememberUpdatedState` acts makes a mutable State out of the Player and always gets its latest value. One can think of it as creating a reference to the Player object and telling the lambdas to always resolve that reference in the moment, rather than hold onto the Player than was passed-by-value. This change is a precursor to a better lifecycle management of Player and Surface in demo-compose. PiperOrigin-RevId: 705529626
This commit is contained in:
parent
684273e4e1
commit
beda44520a
@ -24,6 +24,8 @@ import androidx.compose.foundation.AndroidEmbeddedExternalSurface
|
|||||||
import androidx.compose.foundation.AndroidExternalSurface
|
import androidx.compose.foundation.AndroidExternalSurface
|
||||||
import androidx.compose.foundation.AndroidExternalSurfaceScope
|
import androidx.compose.foundation.AndroidExternalSurfaceScope
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
@ -44,11 +46,16 @@ import androidx.media3.common.util.UnstableApi
|
|||||||
@UnstableApi
|
@UnstableApi
|
||||||
@Composable
|
@Composable
|
||||||
fun PlayerSurface(player: Player, surfaceType: @SurfaceType Int, modifier: Modifier = Modifier) {
|
fun PlayerSurface(player: Player, surfaceType: @SurfaceType Int, modifier: Modifier = Modifier) {
|
||||||
|
// Player might change between compositions,
|
||||||
|
// we need long-lived surface-related lambdas to always use the latest value
|
||||||
|
val currentPlayer by rememberUpdatedState(player)
|
||||||
val onSurfaceCreated: (Surface) -> Unit = { surface ->
|
val onSurfaceCreated: (Surface) -> Unit = { surface ->
|
||||||
if (player.isCommandAvailable(Player.COMMAND_SET_VIDEO_SURFACE)) player.setVideoSurface(surface)
|
if (currentPlayer.isCommandAvailable(Player.COMMAND_SET_VIDEO_SURFACE))
|
||||||
|
player.setVideoSurface(surface)
|
||||||
}
|
}
|
||||||
val onSurfaceDestroyed: () -> Unit = {
|
val onSurfaceDestroyed: () -> Unit = {
|
||||||
if (player.isCommandAvailable(Player.COMMAND_SET_VIDEO_SURFACE)) player.clearVideoSurface()
|
if (currentPlayer.isCommandAvailable(Player.COMMAND_SET_VIDEO_SURFACE))
|
||||||
|
player.clearVideoSurface()
|
||||||
}
|
}
|
||||||
val onSurfaceInitialized: AndroidExternalSurfaceScope.() -> Unit = {
|
val onSurfaceInitialized: AndroidExternalSurfaceScope.() -> Unit = {
|
||||||
onSurface { surface, _, _ ->
|
onSurface { surface, _, _ ->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user