diff --git a/app/src/main/java/com/hikoncont/manager/ScreenCaptureManager.kt b/app/src/main/java/com/hikoncont/manager/ScreenCaptureManager.kt index f13b07a..2124065 100644 --- a/app/src/main/java/com/hikoncont/manager/ScreenCaptureManager.kt +++ b/app/src/main/java/com/hikoncont/manager/ScreenCaptureManager.kt @@ -192,7 +192,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) { } /** - * � 清空ImageReader中所有已acquired的Image,释放缓冲区槽位 + * 清空ImageReader中所有已acquired的Image,释放缓冲区槽位 * 当acquireLatestImage抛出maxImages异常时调用 */ private fun drainImageReader() { @@ -450,6 +450,21 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) { while (isCapturing) { try { + // Surface有效性检测:BufferQueue被系统abandoned后立即回退 + // 防止acquireLatestImage()持续返回null触发无限重建循环 + val currentSurface = imageReader?.surface + if (currentSurface == null || !currentSurface.isValid) { + Log.w(TAG, "ImageReader Surface已失效(null=${currentSurface == null}, isValid=${currentSurface?.isValid}), 停止采集并回退到无障碍截图") + cleanupVirtualDisplayOnly() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + enableAccessibilityScreenshotMode() + startAccessibilityScreenCapture() + } else { + startFallbackCapture() + } + return@launch + } + // 安全获取Image,防止maxImages溢出 val image = try { imageReader?.acquireLatestImage() @@ -563,8 +578,11 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) { setupMediaProjectionResources() consecutiveFailures = 0 - if (virtualDisplay == null) { - Log.w(TAG, "VirtualDisplay 重建失败,回退到无障碍截图") + // 重建后验证VirtualDisplay和Surface有效性 + val rebuiltSurface = imageReader?.surface + if (virtualDisplay == null || rebuiltSurface == null || !rebuiltSurface.isValid) { + Log.w(TAG, "VirtualDisplay 重建后无效(vd=${virtualDisplay != null}, surface=${rebuiltSurface != null}, valid=${rebuiltSurface?.isValid}), 回退到无障碍截图") + cleanupVirtualDisplayOnly() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { enableAccessibilityScreenshotMode() startAccessibilityScreenCapture() @@ -1222,6 +1240,17 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) { if (virtualDisplay != null) { Log.i(TAG, "VirtualDisplay创建成功") + // 验证Surface有效性,防止BufferQueue已被abandoned + val createdSurface = imageReader?.surface + if (createdSurface == null || !createdSurface.isValid) { + Log.e(TAG, "VirtualDisplay创建后Surface无效(null=${createdSurface == null}, isValid=${createdSurface?.isValid}), 清理资源") + virtualDisplay?.release() + virtualDisplay = null + imageReader?.close() + imageReader = null + return + } + // Android 15:VirtualDisplay创建成功后触发权限申请处理 if (Build.VERSION.SDK_INT >= 35) { Log.i(TAG, "Android 15:VirtualDisplay创建成功,触发权限申请处理") @@ -2462,6 +2491,18 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) { if (virtualDisplay != null) { Log.i(TAG, "Android 15 VirtualDisplay完全重新创建成功") + // 验证Surface有效性 + val rebuiltSurface = imageReader?.surface + if (rebuiltSurface == null || !rebuiltSurface.isValid) { + Log.e(TAG, "Android 15 VirtualDisplay重建后Surface无效, 放弃") + virtualDisplay?.release() + virtualDisplay = null + imageReader?.close() + imageReader = null + isVirtualDisplayRecreating = false + return false + } + // Android 15:VirtualDisplay重新创建成功后触发权限申请处理 Log.i(TAG, "Android 15:VirtualDisplay重新创建成功,触发权限申请处理") triggerAndroid15PermissionRequest("重新初始化VirtualDisplay")