fix: defer view removal to avoid AOSP dispatchWindowVisibilityChanged NPE
This commit is contained in:
@@ -1390,23 +1390,21 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener {
|
||||
trackSelector = null
|
||||
assHandler = null
|
||||
|
||||
surfaceView?.holder?.removeCallback(surfaceCallback)
|
||||
val cb = surfaceCallback
|
||||
val sv = surfaceView
|
||||
overlayLayoutListener?.let { listener ->
|
||||
val contentView = activity.findViewById<ViewGroup>(android.R.id.content)
|
||||
contentView.viewTreeObserver.removeOnGlobalLayoutListener(listener)
|
||||
}
|
||||
overlayLayoutListener = null
|
||||
|
||||
// Remove SurfaceView from container synchronously — triggers
|
||||
// onDetachedFromWindow which properly unregisters PositionUpdateListener
|
||||
// and releases SurfaceControl before the render thread can access it.
|
||||
// Defer all view removal to avoid AOSP bug where
|
||||
// dispatchWindowVisibilityChanged iterates stale children array
|
||||
// when removeView() runs during an active performTraversals pass.
|
||||
val container = surfaceContainer
|
||||
surfaceView?.let { container?.removeView(it) }
|
||||
subtitleView?.let { container?.removeView(it) }
|
||||
|
||||
// Defer empty container removal (plain FrameLayout, no SurfaceControl)
|
||||
val contentView = activity.findViewById<ViewGroup>(android.R.id.content)
|
||||
contentView.post {
|
||||
sv?.holder?.removeCallback(cb)
|
||||
container?.let { contentView.removeView(it) }
|
||||
}
|
||||
surfaceContainer = null
|
||||
|
||||
@@ -809,15 +809,14 @@ class MpvPlayerCore(private val activity: Activity) :
|
||||
}
|
||||
overlayLayoutListener = null
|
||||
|
||||
// Remove SurfaceView synchronously (keep callback so surfaceDestroyed
|
||||
// fires → MPVLib.detachSurface()), then remove callback after.
|
||||
// Defer all view removal to avoid AOSP bug where
|
||||
// dispatchWindowVisibilityChanged iterates stale children array
|
||||
// when removeView() runs during an active performTraversals pass.
|
||||
val sv = surfaceView
|
||||
val container = surfaceContainer
|
||||
surfaceView?.let { container?.removeView(it) }
|
||||
surfaceView?.holder?.removeCallback(this)
|
||||
|
||||
// Defer empty container removal (plain FrameLayout, no SurfaceControl)
|
||||
val contentView = activity.findViewById<ViewGroup>(android.R.id.content)
|
||||
contentView.post {
|
||||
sv?.holder?.removeCallback(this)
|
||||
container?.let { contentView.removeView(it) }
|
||||
}
|
||||
surfaceContainer = null
|
||||
|
||||
Reference in New Issue
Block a user