From b62a3501d2e7ce44d50db06fa2a3ad0debc886d5 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Sun, 15 Feb 2026 18:10:46 +0100 Subject: [PATCH] fix: SurfaceView ANR on Android --- .../com/edde746/plezy/exoplayer/ExoPlayerCore.kt | 10 ++++++++-- .../main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt | 6 +++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt index fac7b8c1..1b5eb9be 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt @@ -1253,6 +1253,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { abandonAudioFocus() audioManager = null + exoPlayer?.clearVideoSurface() exoPlayer?.removeListener(this) exoPlayer?.release() exoPlayer = null @@ -1265,9 +1266,14 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { contentView.viewTreeObserver.removeOnGlobalLayoutListener(listener) } + // Post view removal to next frame to avoid SurfaceControl race on render thread val contentView = activity.findViewById(android.R.id.content) - surfaceContainer?.let { contentView.removeView(it) } - subtitleView?.let { contentView.removeView(it) } + val container = surfaceContainer + val subtitle = subtitleView + contentView.post { + container?.let { contentView.removeView(it) } + subtitle?.let { contentView.removeView(it) } + } surfaceContainer = null surfaceView = null subtitleView = null diff --git a/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt index 3361b0c0..9d913701 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt @@ -723,8 +723,12 @@ class MpvPlayerCore(private val activity: Activity) : contentView.viewTreeObserver.removeOnGlobalLayoutListener(listener) } + // Post view removal to next frame to avoid SurfaceControl race on render thread val contentView = activity.findViewById(android.R.id.content) - surfaceContainer?.let { contentView.removeView(it) } + val container = surfaceContainer + contentView.post { + container?.let { contentView.removeView(it) } + } surfaceContainer = null surfaceView = null