You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.4 KiB
2.4 KiB
主线程为什么没有 ANR?
- 了解 ANR 的触发的原理
- 了解应用大致启动流程
- 了解线程的消息循环机制
- 了解应用和系统服务通信过程
ANR 是什么?
final void appNotResponding(ProcessRecord app, ...){
Message msg = Message.obtain();
msg.what = SHOW_NOT_RESPONDING_MSG;
mUiHandler.sendMessage(msg);
}
// SystemService 进程
Dialog d = new AppNotRespondingDialog(...);
d.show();
ANR 场景有哪些?
- Service Timeout
- BroadcastQueue Timeout
- ContentProvider Timeout
- InputDispatching Timeout
以 Service 为例,看一下 ANR 是怎么触发的?
void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInfg){
bumpServiceExecutingLocked(r, execInFg, "create");
app.thread.scheduleCreateService(r, r.serviceInfo, ...);
}
void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why){
scheduleServiceTimeoutLocked(r.app);
}
void scheduleServiceTimeoutLocked(ProcessRecord proc){
long now = SystemClock.uptimeMillis();
Message msg = mAm.mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
mAm.mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
}
void serviceTimeout(ProcessRecord proc){
mAm.appNotResponding(proc, ...);
}
// 应用端处理 Service 请求
private void handleCreateService(CreateServiceData data) {
service = (Service)cl.loadClass(data.info.name).newInstance();
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, ...);
service.onCreate();
ActivityManagerNative.getDefault().serviceDoneExecuting(...);
}
private void serviceDoneExecutingLocked(ServiceRecord r, ...){
mAm.mHandler.removeMessage(SERVICE_TIMEOUT_MSG, r.app);
}
往主线程发消息:
@Override
void scheduleLaunchActivity(Intent intent, IBinder token, ...){
sendMessage(H.LAUNCH_ACTIVITY, r);
}
void scheduleCreateService(IBinder token, ...){
sendMessage(H.CREATE_SERVICE, s);
}
void scheduleReceiver(Intent intent, ActivityInfo info, ...){
sendMessage(H.RECEIVER, r);
}
总结
- ANR 是应用没有在规定的时间内完成 AMS 指定的任务导致的
- AMS 请求调用应用端 binder 线程,再丢消息去唤醒主线程来处理
- ANR 不是因为主线程 loop 循环,而是因为主线程有耗时任务