fix: 修复启动时三个应用层报错问题

- MediaProjectionManager初始化提前到onCreate开头,避免多个return路径跳过初始化导致后续null
- InputController剪贴板访问添加SecurityException防护,非前台时安全降级而非崩溃
- HuaweiAuthorizationHandler剪贴板访问添加异常捕获,防止ClipboardService拒绝访问
- SocketIO连接错误区分瞬态错误(xhr poll/timeout)和持久错误,瞬态错误降级为WARN
- SocketIO connect方法添加URL格式验证和空值检查
This commit is contained in:
wdvipa
2026-02-15 15:40:55 +08:00
parent 410219f382
commit cdc4606574
4 changed files with 90 additions and 30 deletions

View File

@@ -271,22 +271,34 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
private val maxGalleryImageSize = 2 * 1024 * 1024 // 2MB
/**
* 连接到Socket.IO v4服务器
* Connect to Socket.IO v4 server
*/
suspend fun connect(serverUrl: String) {
try {
this.serverUrl = serverUrl // 保存服务器地址
Log.i(TAG, "🚀 连接到Socket.IO v4服务器: $serverUrl")
this.serverUrl = serverUrl
Log.i(TAG, "Connecting to Socket.IO v4 server: $serverUrl")
// ✅ 新增:验证配置一致性
// Validate server URL format
if (serverUrl.isBlank()) {
Log.e(TAG, "Server URL is empty, cannot connect")
return
}
// Validate URL format
val validatedUrl = try {
java.net.URI.create(serverUrl)
serverUrl
} catch (e: Exception) {
Log.e(TAG, "Invalid server URL format: $serverUrl", e)
return
}
// Config consistency check
val savedUrl = com.hikoncont.util.ConfigWriter.getCurrentServerUrl(service)
if (savedUrl != null && savedUrl != serverUrl) {
Log.w(TAG, "⚠️ 配置不一致!当前连接地址: $serverUrl, 配置文件地址: $savedUrl")
Log.i(TAG, "🔄 使用配置文件中的地址重新连接: $savedUrl")
Log.w(TAG, "Config mismatch! Current: $serverUrl, Config: $savedUrl, using config URL")
connect(savedUrl)
return
} else if (savedUrl == serverUrl) {
Log.i(TAG, "✅ 配置验证通过,地址一致: $serverUrl")
}
// ✅ Socket.IO v4客户端配置 - 增强稳定性优化 + 随机化重连避免雪崩
@@ -425,8 +437,21 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
}
socket.on(Socket.EVENT_CONNECT_ERROR) { args ->
val error = if (args.isNotEmpty()) args[0].toString() else "unknown"
Log.e(TAG, "Socket.IO v4 连接错误: $error")
val error = if (args.isNotEmpty()) args[0] else null
val errorMsg = error?.toString() ?: "unknown"
// Downgrade to WARN for expected transient errors (xhr poll = server unreachable)
val isTransientError = errorMsg.contains("xhr poll error") ||
errorMsg.contains("timeout") ||
errorMsg.contains("websocket error")
if (isTransientError) {
Log.w(TAG, "Socket.IO connection error (transient, will auto-retry): $errorMsg")
} else {
Log.e(TAG, "Socket.IO connection error: $errorMsg")
}
// Log root cause if available
if (error is Exception && error.cause != null) {
Log.w(TAG, "Socket.IO error root cause: ${error.cause?.javaClass?.simpleName}: ${error.cause?.message}")
}
connectionFailureCount++
updateNetworkQualityScore(false, "connect_error", 0)
}