fix: BufferQueue abandoned导致进程崩溃重启
- 采集循环每帧检测imageReader.surface.isValid, Surface失效时立即回退到无障碍截图 - setupMediaProjectionResources中VirtualDisplay创建后验证Surface有效性 - 采集循环中VirtualDisplay重建后验证Surface有效性, 无效则直接回退 - reinitializeVirtualDisplayForAndroid15中重建后验证Surface有效性 - 清理drainImageReader注释中的乱码字符
This commit is contained in:
@@ -192,7 +192,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* <20> 清空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")
|
||||
|
||||
Reference in New Issue
Block a user