android ANR源码分析 --- 之一
来源:互联网 发布:网络取代电视 编辑:程序博客网 时间:2024/05/20 06:52
概述:
ANR(ApplicationNot responding),是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间
能未能得到有效响应或者响应时间过长,都会造成ANR。一般地,这时往往会弹出一个提示框,告知用户当前xxx未响应,用户可选择
继续等待或者Force Close。
那么哪些场景会造成ANR呢?
1,Service Timeout:服务在20s内未执行完成;
2,BroadcastQueueTimeout:比如前台广播在10s内执行完成
3,ContentProviderTimeout:内容提供者执行超时
4,inputDispatchingTimeout: 输入事件分发超时5s,包括按键分发事件的超时。
1, Service Timeout
ServiceTimeout触发时机,简单说就是AMS中的mHandler收到SERVICE_TIMEOUT_MSG消息时触发。
在service启动时,最后会调用system_server进程中的ActiveServices的attachApplicationLocked方法,然后调用realStartServiceLocked方法完成服务的启动。
详细过程见http://blog.csdn.net/u012439416/article/details/77394649
整个过程主要分为3个部分:
1,在启动service之前发送SERVICE_TIMEOUT_MSG 消息;
2,如果service顺利启动,则删除SERVICE_TIMEOUT_MSG 消息;
3,如果SERVICE_TIMEOUT_MSG 未删除,时间到后就会发生ANR。
1.1 发送消息
ActiveServices的realStartServiceLocked方法在调用service的OnCreate方法之前就会发送消息,调用流程图如下,
realStartServiceLocked方法调用如下,
bumpServiceExecutingLocked(r, execInFg, "create");//发送消息•••app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState);//调用service的OnCreate方法
在bumpServiceExecutingLocked方法中回调用scheduleServiceTimeoutLocked方法发送SERVICE_TIMEOUT_MSG 消息。
scheduleServiceTimeoutLocked方法如下,
long now = SystemClock.uptimeMillis();Message msg = mAm.mHandler.obtainMessage(ActivityManagerService.SERVICE_TIMEOUT_MSG);msg.obj = proc;mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
首先获取系统的当前时间,然后利用AMS的mHandler变量构造SERVICE_TIMEOUT_MSG消息,最后调用AMS的mHandler变量的sendMessageAtTime方法发送消息。
SERVICE_TIMEOUT和SERVICE_BACKGROUND_TIMEOUT定义如下,
// How long we wait for a service to finish executing.static final int SERVICE_TIMEOUT = 20*1000;// How long we wait for a service to finish executing.static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
因此, 对于前台服务,则超时为SERVICE_TIMEOUT,即timeout=20s;
对于后台服务,则超时为SERVICE_BACKGROUND_TIMEOUT,即timeout=200s;
1.2 删除消息
在比较多的地方会删除消息,
比如,在realStartServiceLocked方法中
app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState);
调用service的OnCreate方法时进程挂掉之后会调用serviceDoneExecutingLocked方法删除消息。
catch (DeadObjectException e) { Slog.w(TAG, "Application dead when creating service " + r); mAm.appDiedLocked(app); throw e;} finally { if (!created) { // Keep the executeNesting count accurate. final boolean inDestroying = mDestroyingServices.contains(r); serviceDoneExecutingLocked(r, inDestroying, inDestroying);
或者在sendServiceArgsLocked方法中,启动service抛出异常也会调用serviceDoneExecutingLocked方法删除消息。
if (caughtException != null) { // Keep nesting count correct final boolean inDestroying = mDestroyingServices.contains(r); serviceDoneExecutingLocked(r, inDestroying, inDestroying);
app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState);
此处会调用ActivityThread的内部类ApplicationThread的scheduleCreateService方法,最后会调用handleCreateService方法。
ActivityThread的handleCreateService方法主要逻辑如下,
1,加载service 对象,
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);Service service = null;try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance();
2,调用service的onCreate方法,
Application app = packageInfo.makeApplication(false, mInstrumentation);service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault());service.onCreate();mServices.put(data.token, service);
3,成功调用service的onCreate方法之后,跨进程调用AMS的serviceDoneExecuting方法删除消息。
try { ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
AMS的serviceDoneExecuting方法如下,
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
直接调用ActiveServices的serviceDoneExecutingLocked方法.
由此可见,删除SERVICE_TIMEOUT_MSG 消息一般通过ActiveServices的serviceDoneExecutingLocked方法。
serviceDoneExecutingLocked方法逻辑如下,
if (r.app.executingServices.size() == 0) { if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, "No more executingServices of " + r.shortName);mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
如果当前服务所在进程中没有正在执行的service,就删除SERVICE_TIMEOUT_MSG消息。
1.3 处理消息
AMS中内部类MainHandler的handleMessage方法对SERVICE_TIMEOUT_MSG消息处理如下,
mServices.serviceTimeout((ProcessRecord)msg.obj);
调用ActiveServices的serviceTimeout方法进行处理,
serviceTimeout方法逻辑如下,
if (anrMessage != null) { mAm.appNotResponding(proc, null, null, false, anrMessage);}
调用AMS的appNotResponding方法统一处理。处理过程后面详细论述。
其中, anrMessage 字符串为 executing service [发送超时serviceRecord信息]
- android ANR源码分析 --- 之一
- android-ANR源码分析
- Android 源码分析ANR
- Android ANR源码原理分析
- android ANR源码分析 --- 之二
- android ANR源码分析 --- 之三
- android ANR源码分析 --- 之四
- Android-ANR-Android ANR分析
- 【Android】【ANR】如何分析解决Android ANR
- Android ANR问题分析
- [Android] 分析ANR错误
- android anr分析方法
- android anr分析方法
- 【转】Android ANR分析
- Android ANR Log分析
- android anr分析方法
- android ANR分析
- android ANR 分析
- Kafka
- Java-StringBuffer类
- 正则表达式+词频统计+TF-IDF及其算法
- Python3简单爬虫抓取网页图片
- bzoj 3064: Tyvj 1518 CPU监控 线段树维护历史最大值
- android ANR源码分析 --- 之一
- java 存储机制
- Java中方法的参数传递机制
- Spring4知识汇总
- linux c++ 服务器端开发面试必看书籍
- 数据分析之Matplotlib绘图-02
- 面试准备(算法编程)
- java基础知识--抽象类和接口
- Webservice学习(一)--Webservice的相关概念