Android android.os.DeadSystemException解决方案

Android DeadSystemException 出现情况是被系统杀掉服务导致出现的原因,一般出现在后台用户无感知。

1.出错堆栈:

image.png

2.源码分析

 private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to start service " + s
                            + " with " + data.args + ": " + e.toString(), e);
                }
            }
        }
    }

3.解决思路

是否抛出异常是有mInstrumentation.onException(s, e)来判断的,是否可以hook住 Instrumentation。重写onException函数,判断不上报异常。

4.解决方案

Application hook住Instrumentation 是有自己定义的对象

MyApplication.java

 public void onCreate() {
        super.onCreate();
      setMyInstrumentation()
    }
 public static class MyInstrumentation extends Instrumentation {
        @Override
        public boolean onException(Object obj, Throwable e) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                FTLog.i(TAG,"MyInstrumentation  onException "+obj);
                if(e.toString().contains("DeadSystemException")){
                    return true;
                }
            return super.onException(obj,e);
        }
    }

    private void setMyInstrumentation(){
        try {
            MyInstrumentation ins = new MyInstrumentation();
            Class cls = Class.forName("android.app.ActivityThread"); // ActivityThread被隐藏了,所以通过这种方式获得class对象
            Method mthd = cls.getDeclaredMethod("currentActivityThread", (Class[]) null); // 获取当前ActivityThread对象引用
            Object currentAT = mthd.invoke(null, (Object[]) null);
            Field mInstrumentation = currentAT.getClass().getDeclaredField("mInstrumentation");
            mInstrumentation.setAccessible(true);//设置private变量为可读取
            mInstrumentation.set(currentAT, ins); // 修改ActivityThread.mInstrumentation值
        }catch (Exception e){
             e.printStackTrace();
        }
    }

5.现存问题

这样处理是不会报异常了,但是Services也是不会正常启动起来。不过出现这种情况,一般都是进程马上要被系统杀掉了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容