Android源码分析启动Service服务超时ANR异常,到底多久会超时ANR看源代码一目了然
- Android启动Service超时ANR异常源代码分析
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
...
//其中Build.HW_TIMEOUT_MULTIPLIER一般为1
// How long we wait for a service to finish executing. --普通服务20秒
static final int SERVICE_TIMEOUT = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
// How long the startForegroundService() grace period is to get around to
// calling startForeground() before we ANR + stop it. --前台服务10秒
static final int SERVICE_START_FOREGROUND_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
...
//1.发送ActivityManagerService.SERVICE_TIMEOUT_MSG延迟消息,时间到之前如果该消息被移除了
//就不会出现ANR,否则时间到了执行该消息,抛出ANR异常。ANR原理是这样滴。。。
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageDelayed(msg,
proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
//3.服务启动完成后调用该方法,移除SERVICE_TIMEOUT_MSG消息就不会触发ANR异常。
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
boolean finishing) {
...
if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
"No more executingServices of " + r.shortInstanceName);
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
...
}
//4.服务启动超时处理,就是我们常见的ANR报错
void serviceTimeout(ProcessRecord proc) {
...
if (timeout != null && mAm.mProcessList.mLruProcesses.contains(proc)) {//超时了
Slog.w(TAG, "Timeout executing service: " + timeout);
StringWriter sw = new StringWriter();
PrintWriter pw = new FastPrintWriter(sw, false, 1024);
pw.println(timeout);
timeout.dump(pw, " ");
pw.close();
mLastAnrDump = sw.toString();
mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
anrMessage = "executing service " + timeout.shortInstanceName;
} else {//还没到时间,继续sendMessageAtTime消息
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
}
...
}
}
frameworks/base/core/java/android/app/ActivityThread.java
//2.服务启动完成后调用该方法,进而调用上面的serviceDoneExecutingLocked方法
private void handleCreateService(CreateServiceData data) {
...
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
...
}
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
//3.服务启动超时后,来到这里SERVICE_TIMEOUT_MSG分歧代码,最后执行mServices.serviceTimeout方法
final class MainHandler extends Handler {
public MainHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {;
case SERVICE_TIMEOUT_MSG: {
mServices.serviceTimeout((ProcessRecord)msg.obj);
} break;
}
}
}
分类:
android系统源码分析
标签:
android系统源码分析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2017-05-28 动态伸缩调整列表头部比如ListView和RecyclerView的HeadView
2017-05-28 提交本地项目到GitHub上