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