parent
521bb3cb6c
commit
589520575d
@ -0,0 +1,81 @@ |
||||
--- |
||||
主线程为什么没有 ANR? |
||||
--- |
||||
|
||||
1. 了解 ANR 的触发的原理 |
||||
2. 了解应用大致启动流程 |
||||
3. 了解线程的消息循环机制 |
||||
4. 了解应用和系统服务通信过程 |
||||
|
||||
#### ANR 是什么? |
||||
|
||||
```java |
||||
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 场景有哪些? |
||||
|
||||
1. Service Timeout |
||||
2. BroadcastQueue Timeout |
||||
3. ContentProvider Timeout |
||||
4. InputDispatching Timeout |
||||
|
||||
以 Service 为例,看一下 ANR 是怎么触发的? |
||||
|
||||
```java |
||||
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); |
||||
} |
||||
``` |
||||
|
||||
往主线程发消息: |
||||
|
||||
```java |
||||
@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); |
||||
} |
||||
``` |
||||
|
||||
#### 总结 |
||||
|
||||
1. ANR 是应用没有在规定的时间内完成 AMS 指定的任务导致的 |
||||
2. AMS 请求调用应用端 binder 线程,再丢消息去唤醒主线程来处理 |
||||
3. ANR 不是因为主线程 loop 循环,而是因为主线程有耗时任务 |
Loading…
Reference in new issue