测试
This commit is contained in:
287
app/src/main/java/com/hikoncont/service/ProcessMonitorService.kt
Normal file
287
app/src/main/java/com/hikoncont/service/ProcessMonitorService.kt
Normal file
@@ -0,0 +1,287 @@
|
||||
package com.hikoncont.service
|
||||
|
||||
import android.app.*
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
import android.os.PowerManager
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* 进程监控服务
|
||||
* 监控主进程状态,在进程被杀死时立即启动恢复机制
|
||||
*/
|
||||
class ProcessMonitorService : Service() {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ProcessMonitorService"
|
||||
private const val CHECK_INTERVAL = 1000L // ✅ 激进:1秒检查一次进程状态
|
||||
private const val NOTIFICATION_ID = 9999
|
||||
private const val CHANNEL_ID = "process_monitor_channel"
|
||||
|
||||
// 进程状态文件路径
|
||||
private const val PROCESS_STATUS_FILE = "process_status.txt"
|
||||
}
|
||||
|
||||
private val serviceScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
private var monitorJob: Job? = null
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private var notificationManager: NotificationManager? = null
|
||||
private var isMonitoring = false
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Log.i(TAG, "🔍 进程监控服务创建")
|
||||
|
||||
// 初始化通知管理器
|
||||
initNotificationManager()
|
||||
|
||||
// 获取WakeLock保活
|
||||
acquireWakeLock()
|
||||
|
||||
// 启动前台服务
|
||||
startForegroundService()
|
||||
|
||||
// 开始监控
|
||||
startMonitoring()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Log.i(TAG, "🔍 进程监控服务启动命令")
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
Log.i(TAG, "🛑 进程监控服务销毁")
|
||||
|
||||
// 释放WakeLock
|
||||
releaseWakeLock()
|
||||
|
||||
// 停止监控
|
||||
stopMonitoring()
|
||||
|
||||
// 启动激进恢复机制
|
||||
scheduleAggressiveRecovery()
|
||||
|
||||
serviceScope.cancel()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||
Log.w(TAG, "🧹 检测到任务被移除(onTaskRemoved),启动激进恢复")
|
||||
scheduleAggressiveRecovery()
|
||||
super.onTaskRemoved(rootIntent)
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化通知管理器
|
||||
*/
|
||||
private fun initNotificationManager() {
|
||||
try {
|
||||
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
"进程监控服务",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
).apply {
|
||||
description = "监控主进程状态"
|
||||
setShowBadge(false)
|
||||
}
|
||||
notificationManager?.createNotificationChannel(channel)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 初始化通知管理器失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动前台服务
|
||||
*/
|
||||
private fun startForegroundService() {
|
||||
try {
|
||||
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
|
||||
.setContentTitle("进程监控服务")
|
||||
.setContentText("正在监控主进程状态")
|
||||
.setSmallIcon(android.R.drawable.ic_dialog_info)
|
||||
.setOngoing(true)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.build()
|
||||
|
||||
startForeground(NOTIFICATION_ID, notification)
|
||||
Log.i(TAG, "✅ 前台服务已启动")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 启动前台服务失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WakeLock保活
|
||||
*/
|
||||
private fun acquireWakeLock() {
|
||||
try {
|
||||
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
wakeLock = powerManager.newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"RemoteControl::ProcessMonitorService"
|
||||
)
|
||||
wakeLock?.acquire(24 * 60 * 60 * 1000L) // 24小时
|
||||
Log.i(TAG, "🔋 ProcessMonitorService WakeLock已获取")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 获取ProcessMonitorService WakeLock失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放WakeLock
|
||||
*/
|
||||
private fun releaseWakeLock() {
|
||||
try {
|
||||
wakeLock?.let {
|
||||
if (it.isHeld) {
|
||||
it.release()
|
||||
Log.i(TAG, "🔋 ProcessMonitorService WakeLock已释放")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 释放ProcessMonitorService WakeLock失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始监控
|
||||
*/
|
||||
private fun startMonitoring() {
|
||||
if (isMonitoring) {
|
||||
Log.w(TAG, "⚠️ 进程监控已在运行")
|
||||
return
|
||||
}
|
||||
|
||||
isMonitoring = true
|
||||
Log.i(TAG, "🔍 开始进程状态监控")
|
||||
|
||||
monitorJob = serviceScope.launch {
|
||||
while (isActive && isMonitoring) {
|
||||
try {
|
||||
// 更新进程状态文件
|
||||
updateProcessStatus()
|
||||
|
||||
// 检查主进程是否存活
|
||||
if (!isMainProcessAlive()) {
|
||||
Log.w(TAG, "⚠️ 检测到主进程死亡,启动恢复机制")
|
||||
scheduleAggressiveRecovery()
|
||||
}
|
||||
|
||||
delay(CHECK_INTERVAL)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 进程监控异常", e)
|
||||
delay(CHECK_INTERVAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止监控
|
||||
*/
|
||||
private fun stopMonitoring() {
|
||||
isMonitoring = false
|
||||
monitorJob?.cancel()
|
||||
Log.i(TAG, "🛑 进程监控已停止")
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新进程状态文件
|
||||
*/
|
||||
private fun updateProcessStatus() {
|
||||
try {
|
||||
val statusFile = File(filesDir, PROCESS_STATUS_FILE)
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val pid = android.os.Process.myPid()
|
||||
|
||||
statusFile.writeText("$pid:$currentTime")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 更新进程状态文件失败", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查主进程是否存活
|
||||
*/
|
||||
private fun isMainProcessAlive(): Boolean {
|
||||
return try {
|
||||
val statusFile = File(filesDir, PROCESS_STATUS_FILE)
|
||||
if (!statusFile.exists()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val content = statusFile.readText()
|
||||
val parts = content.split(":")
|
||||
if (parts.size != 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
val timestamp = parts[1].toLongOrNull() ?: return false
|
||||
val currentTime = System.currentTimeMillis()
|
||||
|
||||
// 如果状态文件超过5秒没有更新,认为进程死亡
|
||||
(currentTime - timestamp) < 5000
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 检查主进程状态失败", e)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动激进恢复机制
|
||||
*/
|
||||
private fun scheduleAggressiveRecovery() {
|
||||
try {
|
||||
Log.i(TAG, "🚀 启动激进恢复机制")
|
||||
|
||||
// 立即启动前台服务
|
||||
val rcfsIntent = Intent(this, RemoteControlForegroundService::class.java).apply {
|
||||
action = "RESTART_SERVICE"
|
||||
}
|
||||
startForegroundService(rcfsIntent)
|
||||
|
||||
// 立即启动保活服务
|
||||
val keepAliveIntent = Intent(this, KeepAliveService::class.java)
|
||||
startService(keepAliveIntent)
|
||||
|
||||
// 使用AlarmManager安排延迟恢复
|
||||
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
|
||||
val rcfsPI = PendingIntent.getForegroundService(
|
||||
this,
|
||||
(System.currentTimeMillis() % 10000).toInt(),
|
||||
rcfsIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val keepAlivePI = PendingIntent.getService(
|
||||
this,
|
||||
(System.currentTimeMillis() % 10000).toInt() + 1,
|
||||
keepAliveIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val triggerAt = System.currentTimeMillis() + 50 // 50ms延迟
|
||||
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, rcfsPI)
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt + 50, keepAlivePI)
|
||||
|
||||
Log.i(TAG, "✅ 激进恢复机制已启动")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 启动激进恢复机制失败", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user