Android Service中全局变量计数应用重启次数每次归零如何解决?
问题根因
- 语法错误:你写的
cmp =+ 1是直接将正1赋值给cmp变量,并未实现累加效果,正确的累加语法是cmp += 1,这是你当前每次计数都异常的直接原因 - 存储方式问题:companion object定义的静态变量生命周期和应用进程完全绑定,如果你没有将Service设置为独立进程,主应用被杀死时整个进程都会销毁,静态变量会自动重置为0;就算Service跑在独立进程,系统因资源紧张回收Service进程时,计数也会丢失。
修复方案
步骤1:修复累加语法+增加持久化存储
用SharedPreferences存储计数器,保证进程重启后计数不会丢失,同时修复累加语法错误,加上重启满3次的日志输出逻辑。
步骤2:可选配置(推荐)
在AndroidManifest.xml中给MonitoringService添加android:process=":monitor"属性,让Service运行在独立进程,避免主应用被杀时连带销毁Service。
修改后代码示例
class MonitoringService: Service() { private lateinit var sp: SharedPreferences private inner class ServiceHandler(looper: Looper) : Handler(looper) { } override fun onCreate() { super.onCreate() Log.e("TEST SERVICE", "Create Service") // 初始化SharedPreferences sp = getSharedPreferences("monitor_config", MODE_PRIVATE) } override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { Log.e("TEST SERVICE", "Start Service") CoroutineScope(Dispatchers.IO).launch { while (true){ isAppRunning(this@MonitoringService, "ch.test.test.mainApp") delay(5000) } } return START_REDELIVER_INTENT } override fun onDestroy() { Log.e("TEST SERVICE", "Destroy Service") super.onDestroy() } override fun onBind(intent: Intent?): IBinder? { TODO("Not yet implemented") } fun isAppRunning(context: Context, packageName: String): Boolean { val activityManager = context.getSystemService(ACTIVITY_SERVICE) as ActivityManager val procInfos = activityManager.runningAppProcesses if (procInfos != null) { for (processInfo in procInfos) { if (processInfo.processName == packageName) { ActivityManager.getMyMemoryState(processInfo) if (processInfo.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){ val app = Intent(context, MainActivity::class.java) app.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // 后台启动Activity必须加这个Flag // 读取原有计数累加 val currentCount = sp.getInt("restart_count", 0) + 1 sp.edit().putInt("restart_count", currentCount).apply() Log.e("TEST SERVICE", "重启次数:$currentCount") // 满3次输出对应日志 if (currentCount >= 3) { Log.e("TEST SERVICE", "主应用重启次数已达3次") // 如果需要重置计数就打开下面的注释 // sp.edit().putInt("restart_count", 0).apply() } startActivity(app) } return true } } } return false } }
额外注意
Android 10及以上版本限制了后台启动Activity的行为,如果你的应用 targetSdkVersion >= 29,需要申请SYSTEM_ALERT_WINDOW权限才能正常在后台拉起主应用界面。
内容的提问来源于stack exchange,提问作者mmmmmmm
相关产品推荐
相关产品推荐

