DeadSystemException: The core Android system has died and is Going through a runtime restart. All
DeadSystemException:
The core Android system has died and is Going through a runtime restart. All running apps will be promptly killed.
Android 核心系统服务已经死亡,正在重启中。全部正在运行的app即将被kill杀死。
更多请阅读,DeadSystemException官方介绍
chatgpt给出的解决答案:
Android中的DeadSystemException是一种非常严重的异常,表示系统已经崩溃。如果不进行处理,应用程序将会崩溃并退出。
处理方式:
先来看下调用栈中抛出异常的地方:
/frameworks/base/core/java/android/app/ActivityThread.java
中handleCreateService():
从源码可知 :
为了进一步了解原因,接着查看bugly上该异常中捕获的日志,发现有几条有效日志:
//系统服务已经die死亡AndroidRuntime: FATAL EXCEPTION: mainAndroidRuntime: Process: com.android.systemui, PID: 19210AndroidRuntime: DeadSystemException: The system died; earlier logs will point to the root causeAppErrors: Process com.android.systemui has crashed too many times: killing!//binder 通讯异常抛出日志JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 104)
根据分析,推断系统服务已经死亡,app进程通过binder与之通讯,会抛出DeadSystemException。
根据FAILED BINDER TRANSACTION
检索,找/frameworks/base/core/jni/android_util_Binder.cpp
。
signalExceptionForError():
从binder通讯源码中可知,当遇到异常返回status(failed_transansaction 和dead_object)时, 会抛出DeadObjectException异常。另外,单次读写超过200k的binder数据,就会抛出TransactionTooLargeException 异常;
原因推断:当app进程创建service 成功后,与ams 通讯过程中,binder 发生异常状态status failed_transansaction,从而抛出异常导致。
解决方案:
采用hook 方式,代理Instrumentation 捕获该异常:
private static class InstrumentationImpl extends Instrumentation{ @Override public boolean onException(Object obj, Throwable e) { return isInterruptException(e); } public static void hookInstrumentation(){ //基本上发生在7.0和7.1设备上 if (Build.VERSION.SDK_INT==Build.VERSION_CODES.N_MR1||Build.VERSION.SDK_INT==Build.VERSION_CODES.N){ try { Instrumentation ins = new InstrumentationImpl(); Class cls = Class.forName("android.app.ActivityThread"); Method mthd = cls.getDeclaredMethod("currentActivityThread", (Class[]) null); Object currentAT = mthd.invoke(null, (Object[]) null); Field mInstrumentation = currentAT.getClass().getDeclaredField("mInstrumentation"); mInstrumentation.setAccessible(true); mInstrumentation.set(currentAT, ins); }catch (Exception e){ e.printStackTrace(); } } } }}private static boolean isInterruptException(Throwable e){ if (e.toString().contains("DeadSystemException")){ //拦截DeadSystemException return true; } return false;}
以上代码,在Application的oncreate()中调用。
还有其他hook 方式,ActivityThread#H 的handler callBack ,也可以通用实现以上效果;
捕获该异常后,需要启动的服务无法启动,Bugly 不会捕捉到该异常,但app进程很可能会被杀死。
先查看调用栈:
查看下crash 所在的源码:
与前面的问题有些不同,当app 进程已经完成Activity销毁过程后,通知ams 过程中,发生系统进程,死亡异常则直接抛出。
解决方案:
App 销毁Activity过程中没有异常捕捉机制,但该调用栈是在ActivityThread 中名为H 的handler中调用的,因此考虑hook 进行异常捕获。
再查看Handler的源码,发现可以为它设置callBack便可以拦截其handleMessage()调用。
编写代码如下所示:
private static class CallBackImpl implements Handler.Callback{ private Handler activityThreadHandler; public CallBackImpl(Handler activityThreadHandler) { this.activityThreadHandler = activityThreadHandler; } @Override public boolean handleMessage(Message msg) { try { activityThreadHandler.handleMessage(msg); }catch (Exception e){ if (!isInterruptException(e)){ //不被拦截的异常,继续抛出 throw e; } } return true; } public static void hook(){ try { if (Build.VERSION.SDK_INT==Build.VERSION_CODES.N_MR1||Build.VERSION.SDK_INT==Build.VERSION_CODES.N){ //获取到ActivityThread Class<?> ActivityThreadClass = Class.forName("android.app.ActivityThread"); Field sCurrentActivityThreadField = ActivityThreadClass.getDeclaredField("sCurrentActivityThread"); sCurrentActivityThreadField.setAccessible(true); Object ActivityThread = sCurrentActivityThreadField.get(null); //获取到ActivityThread中的handler Field mHField=ActivityThreadClass.getDeclaredField("mH"); mHField.setAccessible(true); Handler mHandler=(Handler) mHField.get(ActivityThread); //给handler添加callback监听器,拦截 Field mCallBackField = Handler.class.getDeclaredField("mCallback"); mCallBackField.setAccessible(true); mCallBackField.set(mHandler, new CallBackImpl(mHandler)); } }catch (Exception e){ e.printStackTrace(); } }}private static boolean isInterruptException(Throwable e){ if (e.toString().contains("DeadSystemException")){ //拦截DeadSystemException return true; } return false;}
以上代码,在Application的oncreate()中调用
查看源码:
StopInfo 这个任务是在ActivityThread 执行Activity onstop状态时添加的:
handleStopActivity() 是在ActivityThread中H的handler中调用的。
解决方案:
因StopInfo是runnable接口,无法通过Handler的handleMessage()函数进行拦截,因此考虑直接代理H 这个Handler , 通过dispatchMessage()分发,传递给H处理,进行异常捕捉。
private static class HandlerImpl extends Handler { private Handler proxy; public HandlerImpl(Handler proxy) { super(proxy.getLooper()); this.proxy = proxy; } @Override public void dispatchMessage(@NonNull Message msg) { try { proxy.dispatchMessage(msg); } catch (Exception e) { if (!isInterruptException(e)) { //不被拦截的异常,继续抛出 throw e; } } } public static void hook() { try { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1 || Build.VERSION.SDK_INT == Build.VERSION_CODES.N) { //获取到ActivityThread Class<?> ActivityThreadClass = Class.forName("android.app.ActivityThread"); Field sCurrentActivityThreadField = ActivityThreadClass.getDeclaredField("sCurrentActivityThread"); sCurrentActivityThreadField.setAccessible(true); Object ActivityThread = sCurrentActivityThreadField.get(null); //获取到ActivityThread中的handler Field mHField = ActivityThreadClass.getDeclaredField("mH"); mHField.setAccessible(true); Handler mHandler = (Handler) mHField.get(ActivityThread); mHField.set(ActivityThread, new HandlerImpl(mHandler)); } } catch (Exception e) { e.printStackTrace(); } }}private static boolean isInterruptException(Throwable e) { if (e.toString().contains("DeadSystemException")) { //拦截DeadSystemException return true; } return false;}
Hook H 这个Handler 可以解决Activity或者Service 生命周期中该异常的捕获。在Application的oncreate()中调用。
实际上可能其他的线程或者其他的handler 中调用跨进程有关的api都可能会遇到该问题,单纯hook ActivityThread中Handler是无法解决的。
终极解决方案:通过主线程的异常处理器,捕获该异常,自定义Thread.UncaughtExceptionHandler。
private static class ExceptionHandlerImpl implements Thread.UncaughtExceptionHandler{ private final Thread.UncaughtExceptionHandler mOldHandler; public ExceptionHandlerImpl(Thread.UncaughtExceptionHandler mOldHandler) { this.mOldHandler = mOldHandler; } @Override public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) { if (isInterruptException( e)) { // 异常逻辑 1: 继续执行,进程不结束 resumeMainThreadLoop(); // restartApp() 或者直接中断该进程,进行重启重启该app 的逻辑2 return; } if (mOldHandler != null) { mOldHandler.uncaughtException(t, e); } } private void restartApp(Context context){ // 重新启动应用程序或者系统服务 final Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, pendingIntent); // 退出应用程序或者停止服务 System.exit(0); } private void resumeMainThreadLoop() { if (Looper.myLooper() != Looper.getMainLooper()) { return; } try { Looper.loop(); } catch (Exception e) { uncaughtException(Thread.currentThread(), e); } } public static void init(){ //在bugly初始化或者自定义crash上报组件之后调用 Thread.UncaughtExceptionHandler mOldHandler = Thread.getDefaultUncaughtExceptionHandler(); if (!(mOldHandler instanceof ExceptionHandlerImpl)) { Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandlerImpl(mOldHandler)); } }}
以上代码在bugly或者异常捕获组件之后调用。
来源地址:https://blog.csdn.net/hexingen/article/details/130553448
--结束END--
本文标题: Android System crash DeadSystemException(Service/Activity/终极解决方案)
本文链接: https://lsjlt.com/news/398293.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0