Android android.os.DeadSystemException解決方案

Android DeadSystemException 出現(xiàn)情況是被系統(tǒng)殺掉服務(wù)導(dǎo)致出現(xiàn)的原因,一般出現(xiàn)在后臺(tái)用戶無(wú)感知。

1.出錯(cuò)堆棧:

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)來(lái)判斷的,是否可以hook住 Instrumentation。重寫onException函數(shù),判斷不上報(bào)異常。

4.解決方案

Application hook住Instrumentation 是有自己定義的對(duì)象

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被隱藏了,所以通過(guò)這種方式獲得class對(duì)象
            Method mthd = cls.getDeclaredMethod("currentActivityThread", (Class[]) null); // 獲取當(dāng)前ActivityThread對(duì)象引用
            Object currentAT = mthd.invoke(null, (Object[]) null);
            Field mInstrumentation = currentAT.getClass().getDeclaredField("mInstrumentation");
            mInstrumentation.setAccessible(true);//設(shè)置private變量為可讀取
            mInstrumentation.set(currentAT, ins); // 修改ActivityThread.mInstrumentation值
        }catch (Exception e){
             e.printStackTrace();
        }
    }

5.現(xiàn)存問(wèn)題

這樣處理是不會(huì)報(bào)異常了,但是Services也是不會(huì)正常啟動(dòng)起來(lái)。不過(guò)出現(xiàn)這種情況,一般都是進(jìn)程馬上要被系統(tǒng)殺掉了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容