一、概述
ANR(Application Not responding),是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。一般地,这时往往会弹出一个提示框,告知用户当前xxx未响应,用户可选择继续等待或者Force Close。
那么哪些场景会造成ANR呢?
- Service Timeout:服务在20s内未执行完成;
- BroadcastQueue Timeout:比如前台广播在10s内执行完成
- ContentProvider Timeout:内容提供者执行超时
- inputDispatching Timeout: 输入事件分发超时5s,包括按键分发事件的超时。
二、ANR触发时机
2.1 Service Timeout
Service Timeout触发时机,简单说就是AMS中的mHandler
收到SERVICE_TIMEOUT_MSG
消息时触发。
在前面文章startService流程分析详细介绍Service启动流程,在Service所在进程attach到system_server进程的过程中会调用realStartServiceLocked()
方法
2.1.1 realStartServiceLocked
[-> ActiveServices.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... //发送delay消息(SERVICE_TIMEOUT_MSG),【见小节2.1.2】 bumpServiceExecutingLocked(r, execInFg, "create"); try { ... //最终执行服务的onCreate()方法 app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); } catch (DeadObjectException e) { ... } finally { if (!created) { //当service启动完毕,则remove SERVICE_TIMEOUT_MSG消息【见小节2.1.3】 serviceDoneExecutingLocked(r, inDestroying, inDestroying); ... } } } |
2.1.2 bumpServiceExecutingLocked
该方法的主要工作发送delay消息(SERVICE_TIMEOUT_MSG)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) { ... scheduleServiceTimeoutLocked(r.app); } void scheduleServiceTimeoutLocked(ProcessRecord proc) { if (proc.executingServices.size() == 0 || proc.thread == null) { return; } long now = SystemClock.uptimeMillis(); Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_TIMEOUT_MSG); msg.obj = proc; //当超时后仍没有remove该SERVICE_TIMEOUT_MSG消息,则执行service Timeout流程【见2.1.4】 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT)); } |
- 对于前台服务,则超时为
SERVICE_TIMEOUT
,即timeout=20s; - 对于后台服务,则超时为
SERVICE_BACKGROUND_TIMEOUT
,即timeout=200s;
2.1.3 serviceDoneExecutingLocked
该方法的主要工作是当service启动完成,则移除service Timeout消息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying, boolean finishing) { ... if (r.executeNesting <= 0) { if (r.app != null) { r.app.execServicesFg = false; r.app.executingServices.remove(r); if (r.app.executingServices.size() == 0) { //当前服务所在进程中没有正在执行的service mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, rss="crayon-v">mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r得到有效响应或者响应时间过长,都会造成ANR。一般地,这时往往会弹出一个提示框,告知用户当前xxx未响应,用户可选择继续等待或者Force Close。
那么哪些场景会造成ANR呢?
二、ANR触发时机2.1 Service TimeoutService Timeout触发时机,简单说就是AMS中的 在前面文章startService流程分析详细介绍Service启动流程,在Service所在进程attach到system_server进程的过程中会调用 2.1.1 realStartServiceLocked[-> ActiveServices.java]
2.1.2 bumpServiceExecutingLocked该方法的主要工作发送delay消息(SERVICE_TIMEOUT_MSG)
2.1.3 serviceDoneExecutingLocked该方法的主要工作是当service启动完成,则移除service Timeout消息。
|