Android DeadSystemException 出现情况是被系统杀掉服务导致出现的原因,一般出现在后台用户无感知。
1.出错堆栈:
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也是不会正常启动起来。不过出现这种情况,一般都是进程马上要被系统杀掉了。