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)殺掉了。