如何在应用下次启动时检测此前是否被强制停止?
检测应用上一次是否以强制停止结束的可行方案
以下几种方案可以在应用下次启动时判断上一次是否为强制停止终止:
方案一:SharedPreferences 正常退出标记法
这是最直接可靠的方案,核心逻辑是强制停止会跳过所有正常退出的回调代码,因此可以通过标记区分正常退出和强制停止:
- 实现步骤:
- 在应用正常退出的时机写入标记:
- 可以在主Activity的
onDestroy()中判断,若不是配置变更导致的销毁(通过isChangingConfigurations()判断),就向SharedPreferences写入normal_exit = true。 - 也可以在
Application类中结合ProcessLifecycleOwner监听应用完全退出的时机写入标记。
- 可以在主Activity的
- 下次启动时(比如
Application的onCreate()):- 读取SharedPreferences中的
normal_exit标记,若标记不存在或为false,则说明上一次是强制停止结束。 - 读取后立即将标记设为
false,避免后续启动误判。
- 读取SharedPreferences中的
- 在应用正常退出的时机写入标记:
- 示例代码(Kotlin):
// 正常退出时写入标记 override fun onDestroy() { super.onDestroy() if (!isChangingConfigurations()) { getSharedPreferences("app_exit_state", MODE_PRIVATE) .edit() .putBoolean("normal_exit", true) .apply() } } // 启动时检查 class MyApplication : Application() { override fun onCreate() { super.onCreate() val sp = getSharedPreferences("app_exit_state", MODE_PRIVATE) val isNormalExit = sp.getBoolean("normal_exit", false) if (!isNormalExit) { // 上一次是强制停止结束 } // 重置标记 sp.edit().putBoolean("normal_exit", false).apply() } }
方案二:ProcessLifecycleOwner 生命周期监听
利用AndroidX的生命周期组件监听应用的全局生命周期,区分正常后台退出和强制停止:
- 原理:强制停止会直接终止进程,不会触发应用的
onDestroy回调;而正常退出(如手动划掉应用)会触发完整的生命周期回调。 - 实现步骤:
- 依赖AndroidX生命周期库,在
Application中注册全局生命周期观察者:ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { super.onDestroy(owner) // 正常销毁时标记 getSharedPreferences("app_lifecycle", MODE_PRIVATE) .edit() .putBoolean("normal_destroy", true) .apply() } }) - 启动时读取
normal_destroy标记:- 若标记不存在,说明上一次进程被强制终止;若标记为
true,则是正常退出,之后重置标记即可。
- 若标记不存在,说明上一次进程被强制终止;若标记为
- 依赖AndroidX生命周期库,在
方案三:系统日志检查(不推荐)
强制停止应用时系统会输出相关日志,但该方案局限性大:
- 需要申请
READ_LOGS权限,Android 10及以上版本中该权限被限制,普通应用无法获取。 - 不同厂商的日志格式可能存在差异,兼容性差。
- 示例代码(仅作参考):
fun checkForceStopLog(): Boolean { val process = Runtime.getRuntime().exec("logcat -d *:S ActivityManager:I") val reader = BufferedReader(InputStreamReader(process.inputStream)) var line: String? val packageName = packageName while (reader.readLine().also { line = it } != null) { if (line?.contains("Force stopping $packageName") == true) { return true } } return false }
补充说明
你提到的WorkManager的WorkInfo无法用于判断,是因为WorkManager的任务记录是持久化存储的,强制停止应用不会清除这些记录,因此无法通过它区分正常退出和强制停止。
内容的提问来源于stack exchange,提问作者Viewed
相关产品推荐
相关产品推荐

