写点什么

Android-Service-ANR- 的监控机制,flutter 文档

用户头像
Android架构
关注
发布于: 刚刚

//ActivityThread 代码:private void handleCreateService(CreateServiceData data) {...//省略


try {if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);


ContextImpl context = ContextImpl.createAppContext(this, packageInfo);context.setOuterContext(service);


Application app = packageInfo.makeApplication(false, mInstrumentation);service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());service.onCreate();//调用 onCreate()mServices.put(data.token, service);try {//跨进程传达 service 创建成功。ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}} catch (Exception e) {if (!mInstrumentation.onException(service, e)) {throw new RuntimeException("Unable to create service " + data.info.name


  • ": " + e.toString(), e);}}}


由上面的核心代码片段可以看出,最终 Service 的创建流程会由 sys_server 进程中的 AMS,跨进程调用 ApplicationThread,在 App 进程通过 Handler 发送消息的形式,执行 handleCreateService(),调用 Service.onCreate()后,再跨进程通知 AMSserviceDoneExecuting()。走到这里,Service 在 App 进程就创建完毕了。onCreate()执行完成。


这一步的流程中,埋下的炸弹时间也在悄然流逝。我们继续往下看,接下来就看 AMS 中如何处理炸弹了。


AMS 被调用到了 serviceDoneExecuting() 方法后,会调用 AS 的 serviceDoneExecutingLoc


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ked()。 在处理了 Service.START_STICKY 等各种乱七八糟的标记位之后,走到 serviceDoneExecutingLocked()方法,这里真正执行到了“拆除炸弹"的过程,将此前埋入的延时消息 remove。


<pre language="javascript" code_block="true">private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,boolean finishing) {//省略...r.executeNesting--;if (r.executeNesting <= 0) {if (r.app != null) {if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,"Nesting at 0 of " + r.shortName);r.app.execServicesFg = false;r.app.executingServices.remove(r);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);} else if (r.executeFg) {// Need to re-evaluate whether the app still needs to be in the foreground.for (int i=r.app.executingServices.size()-1; i>=0; i--) {if (r.app.executingServices.valueAt(i).executeFg) {r.app.execServicesFg = true;break;}}}if (inDestroying) {if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,"doneExecuting remove destroying " + r);mDestroyingServices.remove(r);r.bindings.clear();}mAm.updateOomAdjLocked(r.app, true);}r.executeFg = false;if (r.tracker != null) {r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),SystemClock.uptimeMillis());if (finishing) {r.tracker.clearCurrentOwner(r, false);r.tracker = null;}}if (finishing) {if (r.app != null && !r.app.persistent) {r.app.services.remove(r);if (r.whitelistManager) {updateWhitelistManagerLocked(r.app);}}r.app = null;}}}


那么问题来了,如果在调用 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);的时候发现没有该消息了会发生什么呢? 那其实就说明,mAm.mHandler 已经处理了该消息。我们进入到 mAm.mHandler 中去一探究竟,它收到该消息会做什么事情。


<pre language="javascript" code_block="true">final class MainHandler extends Handler {public MainHandler(Looper looper) {super(looper, null, true);}


@Overridepublic void handleMessage(Message msg) {switch (msg.what) {//...省略 case SERVICE_TIMEOUT_MSG: {mServices.serviceTimeout((ProcessRecord)msg.obj);} break;//...省略}//...省略}//...省略


它委托了 AS 去执行 serviceTimeout(),


<pre language="javascript" code_block="true"> void serviceTimeout(ProcessRecord proc) {String anrMessage = null;


synchronized(mAm) {if (proc.executingServices.size() == 0 || proc.thread == null) {return;}final long now = SystemClock.uptimeMillis();final long maxTime = now -(proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);ServiceRecord timeout = null;long nextTime = 0;for (int i=proc.executingServices.size()-1; i>=0; i--) {ServiceRecord sr = proc.executingServices.valueAt(i);if (sr.executingStart < maxTime) {timeout = sr;break;}if (sr.executingStart > nextTime) {nextTime = sr.executingStart;}}if (timeout != null && mAm.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);

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android-Service-ANR-的监控机制,flutter文档