From 8eb716505d44a0073d685616e8f63b50ee3d0ebf Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Mon, 30 Mar 2026 21:42:11 +0200 Subject: [PATCH] fix: mpv dispose ANR on main thread --- .../com/edde746/plezy/mpv/MpvPlayerCore.kt | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) 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 3e8ec21f..7e358396 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 @@ -741,25 +741,16 @@ class MpvPlayerCore(private val activity: Activity) : SurfaceHolder.Callback { pendingVideoOutputRefreshJob?.cancel() pendingVideoOutputRefreshJob = null - // Detach surface from MPV BEFORE removing views to prevent GPU mutex contention + // Clear surface state flags (no native calls on main thread to avoid ANR) val p = player if (p != null) { - try { - runBlocking(Dispatchers.IO) { - p.setProperty("force-window", "no") - p.setProperty("vo", "null") - } - p.detachSurface() - hasAttachedSurface = false - attachedSurface = null - pausedForSurfaceLoss = false - attachedToPlaceholder = false - videoOutputRestoring = false - lastAppliedSurfaceSize = null - videoOutputEpoch += 1L - } catch (e: Exception) { - Log.w(TAG, "Failed to detach surface during dispose", e) - } + hasAttachedSurface = false + attachedSurface = null + pausedForSurfaceLoss = false + attachedToPlaceholder = false + videoOutputRestoring = false + lastAppliedSurfaceSize = null + videoOutputEpoch += 1L } // Capture locals for deferred cleanup @@ -790,10 +781,20 @@ class MpvPlayerCore(private val activity: Activity) : SurfaceHolder.Callback { pendingVideoOutputDisableJob = null isInitialized = false - // Close player on background thread, then remove views + // Detach surface and close player on background thread, then remove views if (p != null) { Thread { try { + // Detach surface BEFORE close to prevent GPU mutex contention with view removal + try { + runBlocking { + p.setProperty("force-window", "no") + p.setProperty("vo", "null") + } + p.detachSurface() + } catch (e: Exception) { + Log.w(TAG, "Failed to detach surface during dispose", e) + } p.close() } catch (e: Exception) { Log.w(TAG, "MPV close failed", e)