Android应用发生JNI致命崩溃后如何通过编程实现自动重启
Android 应用崩溃自动重启实现方案(兼容Android 11+)
Android 11及以上版本对后台启动Activity的行为做了强制限制,普通后台服务无权限在应用退出后直接拉起前台界面,该机制是系统为减少无关应用弹窗打扰用户的设计,因此后台监控服务拉起的方案无法在高版本系统生效。
方案1:原生无依赖实现(兼容Java/Kotlin,覆盖Java层+大部分Native崩溃)
核心逻辑是用系统AlarmManager触发PendingIntent实现重启,触发主体为系统进程,不受后台启动限制,实现步骤如下:
- 自定义全局未捕获异常处理器,替换系统默认实现
- 捕获到崩溃时构造应用启动Intent,封装为
PendingIntent交给AlarmManager延时触发 - 销毁当前崩溃进程,等待系统触发重启
代码示例(Kotlin,自定义Application中实现):
class MyCustomApp : Application() { override fun onCreate() { super.onCreate() // 设置全局异常捕获 Thread.setDefaultUncaughtExceptionHandler { _, _ -> // 此处可添加崩溃日志落盘逻辑,用于后续问题排查 val launchIntent = packageManager.getLaunchIntentForPackage(packageName) launchIntent?.apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) } val restartPendingIntent = PendingIntent.getActivity( applicationContext, 1001, launchIntent, PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE ) // 交给系统AlarmManager延时100ms触发重启,避开进程销毁冲突 val alarmService = getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmService.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 100, restartPendingIntent ) // 杀死当前崩溃进程 android.os.Process.killProcess(android.os.Process.myPid()) exitProcess(1) } } }
需要在AndroidManifest.xml的application标签中声明自定义的Application类:
<application android:name=".MyCustomApp" ... 其他配置 > </application>
方案2:JNI层致命崩溃补充适配
如果是JNI调用触发的Native层致命崩溃(比如SIGSEGV信号错误),Java层的异常处理器可能无法捕获,可通过以下方式处理:
- 引入Native崩溃捕获组件(如Google Breakpad),在Native信号回调中执行和方案1一致的重启逻辑
- 若你的应用已申请
SYSTEM_ALERT_WINDOW悬浮窗权限,可直接在崩溃回调中启动Activity,该权限不受后台启动限制,但需要用户手动授权
注意事项
- 自动重启仅为降级兼容方案,建议优先定位修复JNI第三方库的崩溃根源,避免反复重启影响用户体验
- 若应用需要保活,可配合前台服务使用,前台服务进程不会被系统判定为后台进程,触发启动的限制更少
内容的提问来源于stack exchange,提问作者Volodymyr Olyinyk
相关产品推荐
相关产品推荐

