专栏首页刘望舒Android深入四大组件(二)Service的启动过程

Android深入四大组件(二)Service的启动过程

此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读Android深入四大组件(一)应用程序启动过程这篇文章。

1.ContextImpl到ActivityManageService的调用过程

要启动Service,我们会调用startService方法,它的实现在ContextWrapper中,代码如下所示。 frameworks/base/core/java/android/content/ContextWrapper.java

在startService方法中会调用mBase的startService方法,Context类型的mBase对象具体指的是什么呢?在Android深入四大组件(一)应用程序启动过程这篇文章中我们讲过ActivityThread启动Activity时会调用如下代码创建Activity的上下文环境。

frameworks/base/core/java/android/app/ActivityThread.java

在注释1处创建上下文对象appContext ,并传入Activity的attach方法中,将Activity与上下文对象appContext 关联起来,这个上下文对象appContext 的具体类型是什么,我们接着查看createBaseContextForActivity方法,代码如下所示。

frameworks/base/core/java/android/app/ActivityThread.java

这里可以得出结论,上下文对象appContext 的具体类型就是ContextImpl 。Activity的attach方法中将ContextImpl赋值给ContextWrapper的成员变量mBase中,因此,mBase具体指向就是ContextImpl 。 那么,我们紧接着来查看ContextImpl的startService方法,代码如下所示。 frameworks/base/core/java/android/app/ContextImpl.java.java

startService方法中会return startServiceCommon方法,在startServiceCommon方法中会在注释1处调用ActivityManageService(AMS)的代理对象ActivityManagerProxy(AMP)的startService方法,最终会调用AMS的startService方法。至于注释1处的代码为何会调用AMS的startService方法,在Android深入四大组件(一)应用程序启动过程这篇文章中已经讲过,这里不再赘述。 ContextImpl到ActivityManageService的调用过程如下面的时序图所示。

2.ActivityThread启动Service

我们接着来查看AMS的startService方法。 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

注释1处调用mServices的startServiceLocked方法,mServices的类型是ActiveServices,ActiveServices的startServiceLocked方法代码如下所示。

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

startServiceLocked方法的末尾return了startServiceInnerLocked方法,而startServiceInnerLocked方法中又调用了bringUpServiceLocked方法:

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

在注释1处得到ServiceRecord的processName的值赋值给procName ,其中ServiceRecord用来描述Service的android:process属性。注释2处将procName和Service的uid传入到AMS的getProcessRecordLocked方法中,来查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来记录运行的应用程序进程的信息。注释5处判断Service对应的app为null则说明用来运行Service的应用程序进程不存在,则调用注释5处的AMS的startProcessLocked方法来创建对应的应用程序进程。关于创建应用程序进程请查看Android应用进程启动过程(前篇)Android应用程序进程启动过程(后篇)这两篇文章。注释3处判断如果用来运行Service的应用程序进程存在,则调用注释4处的realStartServiceLocked方法:

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

在realStartServiceLocked方法中调用了app.thread的scheduleCreateService方法。其中app.thread是IApplicationThread类型的,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。ApplicationThread的scheduleCreateService方法如下所示。

frameworks/base/core/java/android/app/ActivityThread.java

首先将要启动的信息封装成CreateServiceData 对象并传给sendMessage方法,sendMessage方法向H发送CREATE_SERVICE消息,H是ActivityThread的内部类并继承Handler。这个过程和应用程序的启动过程(根Activity启动过程)是类似的。我们接着查看H的handleMessage方法。

frameworks/base/core/java/android/app/ActivityThread.java

handleMessage方法根据消息类型,调用了handleCreateService方法:

frameworks/base/core/java/android/app/ActivityThread.java

注释1处获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类。注释2处通过调用LoadedApk的getClassLoader方法来获取类加载器。接着在注释3处根据CreateServiceData对象中存储的Service信息,将Service加载到内存中。注释4处创建Service的上下文环境ContextImpl对象。注释5处通过Service的attach方法来初始化Service。注释6处调用Service的onCreate方法,这样Service就启动了。在注释7处将启动的Service加入到ActivityThread的成员变量mServices中,其中mServices是ArrayMap类型。

最后给出ActivityThread启动Service的时序图。

本文分享自微信公众号 - 刘望舒(liuwangshuAndroid),作者:刘望舒

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-04-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android深入四大组件(三)Service的绑定过程

    前言 我们可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service,建议阅...

    用户1269200
  • Android深入四大组件(四)广播的注册、发送和接收过程

    前言 我们接着来学习Android四大组件中的BroadcastReceiver,广播主要就是分为注册、接收和发送过程。建议阅读此文前请先阅读Android深入...

    用户1269200
  • Android深入四大组件(五)Content Provider的启动过程

    前言 Content Provider做为四大组件之一,通常情况下并没有其他的组件使用频繁,但这不能作为我们不去深入学习它的理由。关于Content Provi...

    用户1269200
  • 开源 | DGCNN 可以表征拓扑结构的点云分割算法,效果SOTA

    点云数据提供了一种灵活的几何表示,可以适用于计算机图形学中的很多应用。他们还包含了很多3D采集设备的原始输出数据。虽然人工设计的点云特征取得了不错的实验结果,但...

    CNNer
  • 节点属性社交网络中的社区检测:一项调查(CS SI)

    原文题目:Community detection in node-attributed social networks: a survey

    用户6853689
  • linux命令

    兜兜毛毛
  • Android开发(第一行代码 第二版) 常见异常和解决办法(基于Android Studio)(二)

    在自定义Dialog的时候,用Glide加载图片时报了一下异常 Caused by: java.lang.IllegalArgumentException: ...

    cutercorley
  • SpringBoot入门建站全系列(三十三)集成validator校验接口数据

    在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,如果我们直接将这些校验写死在代码里,将会遇到这种现象:

    品茗IT
  • Confluence 6 配置 Windows 服务

    当你使用 Start Confluence Automatically on Windows as a Service 的方式启动的时候,你有下面 2 种方式来...

    HoneyMoose
  • JavaMail邮件发送-能发送附件和带背景音乐的邮件的小系统

    这里使用的是JavaMail技术,前台使用了fckeditor做邮件美化,由于只是示例,后台发送时只是将邮件保存在本地,但是可以查看,如果需要实际发送,请参考我...

    Java帮帮

扫码关注云+社区

领取腾讯云代金券