Android源码分析--Service的启动和绑定

简介: Android源码分析--Service的启动和绑定

Service的启动过程


Service的启动和根Activity的启动很类似。Service的启动同样需要保证该应用程序的进程已经被启动。


启动大纲


  1. ContextImpl请求AMS启动Service.


  1. AMS请求ActivityThread启动Service.


ContextImpl请求AMS启动Service


微信截图_20220517185612.png


  • 当我们需要启动一个Service时,我们会使用context.startService。而Context只是一个抽象的类,它的实现是在ContextWrapper中。


  • 在ContextWrapper的startService方法中,又会调用其内部的Context类型的mBase变量,而该变量的创建详见ActivityThreadcreateBaseContextForActivity方法,它的实现类是ContextImpl


  • ContextImplstartService方法中,又会调用其自身的startServiceCommon方法。


  • ContextImplstartServiceCommon方法中,会使用ActivityManager获取AMS的代理IActivityManager,并调用其startService方法。


AMS请求ActivityThread启动Service


QQ截图20220517185720.png


  • AMSstartService方法中调用ActiveServicestartServiceLocked方法,其中调用retrieveServiceLocked用于获取启动服务的Intent参数所对应的ServiceRecord,它主要用于描述一个Service,启动Service所必须的参数。


  • 在ActiveService的startServiceLocked方法中获取到相应的ServiceRecord之后,就会调用其自身的startServiceInnerLocked方法,而它又会去调用bringUpServiceLocked方法。在bringUpServiceLocked方法中主要做了以下三个工作:


(1)获取Service运行所在的进程。


(2)如果Service运行所在的应用程序进程ProcessRecord存在,则调用其自身的realStartServiceLocked方法来启动Service.


(3)如果Service运行所在的应用程序进程ProcessRecord不存在,则需要调用AMS的startProcessLocked方法来启动应用程序进程。


  • ActiveServicerealStartServiceLocked方法中,会使用ProcessRecordIApplicationThread类型的引用(实现类是ActivityThread的内部类ApplicationThread),调用其scheduleCreateService方法。


  • 在ActivityThread的scheduleCreateService方法中,会向其内部类并继承自Handler的H发送CREATE_SERVICE消息,并由H进行处理,最终会调用handleCreateService方法。


  • ActivityThreadhandleCreateService方法中主要做了如下几件事:


(1)获取要启动Service的应用程序的LoadApk(包信息),并通过它获取类的加载器,通过反射创建Service的实例。


(2)调用ContextImplcreateAppContext方法,为Service创建上下文环境ContextImpl对象。


(3)调用Serviceattach方法,对Service进行初始化。


(4)调用ServiceonCreate方法,这样Service就启动了。


Service的绑定过程


除了使用Context的startService来启动Service外,我们也可以通过Context的bindService来绑定Service。绑定Service的过程要比启动Service的过程复杂一些。


启动大纲


  1. ContextImpl请求AMS绑定Service.


  1. AMS请求ActivityThread处理Service绑定.


  1. AMS进行Service的绑定.


ContextImpl请求AMS绑定Service


微信截图_20220517185822.png


  • 当我们需要绑定一个Service时,我们会使用context.bindService。而Context只是一个抽象的类,它的实现是在ContextWrapper中。


  • 在ContextWrapper的bindService方法中,又会调用其内部的Context类型的mBase变量,而该变量的创建详见ActivityThreadcreateBaseContextForActivity方法,它的实现类是ContextImpl


  • ContextImplbindService方法中,又会调用其自身的bindServiceCommon方法。


  • ContextImplbindServiceCommon方法中,首先调用LoadedApkgetServiceDispatcher方法获取ServiceConnection的封装类(本地的代理)IServiceConnection(用于跨进程通信),然后使用ActivityManager获取AMS的代理IActivityManager,调用其bindService方法并将IServiceConnection对象传入。


AMS请求ActivityThread处理Service绑定


微信截图_20220517185908.png


  • AMSbindService方法中调用方法中调用ActiveServicebindServiceLocked方法,其中同样的和startServiceLocked一样调用retrieveServiceLocked用于获取启动服务的Intent参数所对应的ServiceRecord,然后调用ServiceRecordretrieveAppBindingLocked方法来获取应用和服务的绑定信息AppBindRecord,最后调用requestServiceBindingLocked方法,将之前获取的AppBindRecord信息传入,来发出服务绑定的请求。


  • 除此之外,在bindServiceLocked方法调用requestServiceBindingLocked请求绑定前,还调用了bringUpServiceLocked方法去启动服务。


  • ActiveServicerequestServiceBindingLocked方法中最终会调用ActivityThreadscheduleBindService方法,然后封装BindServiceData数据并将其传入sendMessage方法中,向H发送BIND_SERVICE消息。在H对应的消息处理中会调用handleBindService方法。在handleBindService方法中,对未绑定服务的,先后调用Service的onBind方法和AMS的publishService方法;对已绑定服务的,先后调用Service的onRebind方法和AMS的serviceDoneExecuting方法。


微信截图_20220517185942.png



  • publishServiceLocked方法中会调用IServiceConnectionconnected方法来建立服务连接,最终会调用执行LoadApk中的RunConnection任务,执行doConnected方法建立服务绑定连接。


与Service绑定相关的对象类型介绍:


  • ServiceRecord:用于描述一个Service。


  • ProcessRecord:一个进程所包含的信息。


  • ConnectionRecord:用于描述应用程序进程和Service建立的一次通信。


  • AppBindRecord: 用于维护Service与应用进程之间的绑定信息。


  • IntentBindRecord:用于描述绑定Service的Intent信息。


相关文章
|
7月前
|
Android开发
Android 11 添加Service服务SELinux问题
Android 11 添加Service服务SELinux问题
403 1
|
7月前
|
Android开发
Android基础知识:请解释Service是什么,它与IntentService的区别是什么?
Android基础知识:请解释Service是什么,它与IntentService的区别是什么?
117 0
|
6月前
|
调度 Android开发
43. 【Android教程】服务:Service
43. 【Android教程】服务:Service
64 2
|
7月前
|
Android开发
Android Service Call /dev/xxx SELinux
Android Service Call /dev/xxx SELinux
135 1
|
4月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
|
6月前
|
Android开发 Kotlin
Android面试题 之 Kotlin DataBinding 图片加载和绑定RecyclerView
本文介绍了如何在Android中使用DataBinding和BindingAdapter。示例展示了如何创建`MyBindingAdapter`,包含一个`setImage`方法来设置ImageView的图片。布局文件使用`<data>`标签定义变量,并通过`app:image`调用BindingAdapter。在Activity中设置变量值传递给Adapter处理。此外,还展示了如何在RecyclerView的Adapter中使用DataBinding,如`MyAdapter`,在子布局`item.xml`中绑定User对象到视图。关注公众号AntDream阅读更多内容。
106 1
|
7月前
|
存储 监控 Java
Android Service之设备存储空间监控 DeviceStorageMonitorService
Android Service之设备存储空间监控 DeviceStorageMonitorService
153 2
|
7月前
|
Android开发 数据库管理
Android如何在Activity和Service之间传递数据
Android如何在Activity和Service之间传递数据
317 3
|
7月前
|
Android开发
Android Service的两种使用方法
Android Service的两种使用方法
55 2
|
7月前
|
数据可视化 Android开发
[Android 四大组件] --- Service
[Android 四大组件] --- Service
58 0