Android Service启动原理分析
一、概述
Service是Android的四大组件之一,我们可以利用它开启一个后台服务,Service的优先级比较高,一旦其在后台运行即使App处于后台则Service运行的任务也不容易被杀死。了解Service的工作原来除了可以加深对底层的Service机制的理解以外还可以为当前比较流行的热更新做服务(即Service的插件化)
Service分为两种状态一种一种是启动状态,可以做一些后台的任务计算。一种是绑定状态,帮助Service和用户进行交互。
1.启动状态的声明周期为:onCreate——onStartCommon——onDestory
2.绑定状态的生命周期为:onCreate——onBind——onUnBind——onDestroy
在启动状态下原理分为两部分:1.Service和目标App不在同一个进程。2.Service和App在同一个进程
绑定状态下的原理分析也分为两个部分:1.Service和App不再同一个进程。2.Service和App在同一个进程
其实不管是启动状态还是绑定状态的原理都和之前介绍的Activity的启动原理非常的相似,其实都是反反复复的和AMS交互(握手)的过程,然后利用PMS加载包信息,获取ClassLoader,并利用ClassLoader加载类并通过反射实例化的过程。
二、原理分析
先说下启动状态下App和Service不在同一个进程中的情况。这个过程分为五部,先说下原理然后再介绍调用栈。
1.App通知AMS要启动一个Service,并把启动信息发送给Service
2.AMS收到消息后保存信息,并检查service所在的进程是否已经启动了,如果已经启动了就直接打开,如果没有启动就启动一个新的进程
3.App进程启动好以后通知AMS已经启动好了
4.AMS收到App启动好的消息后就翻出保存在ServiceRecord中的信息,并把其发送给App
5.App收到启动信息后启动Service即可
上面所说的是一个大概的步骤,下面将详细说一下这五步的具体实现
1.App调用context.startService方法,在Context.startService方法内部又会调用ActivityManagerNative.getDefault().startService方法,ActivityManagerNative.getDefault()返回的是一个IActivityManager接口,里面存储了四大组件的所有生命周期函数,而ActiivtyManagerProxy是AMS在App的代理对象,其也集成了IActivityManger接口。所以最终会是ActivityManagerProxy.startService把Service的信息发送给AMS
2.AMS通过跨进程通信的方式收到Service的信息后会保存在ServiceRecord中,然后检查Service是否在AndroidManifest.xml中注册,如果没有注册则报错。检查service进程是否已经启动了,如果没有启动则会调用Process.start(android.app.ActivityThread)方法启动一个新的进程。
3.App进程启动是会实例化ActivityThread对象并调用其中的main方法来开启进程,进程启动后会通过ActivityManagerProxy代理对象把ActivityThread对象发送给AMS
4.AMS接收到ActivityThread对象后会把ActivityThread对象包装成为ApplicationThreadProxy对象(app的代理对象),并从ServiceRecord中翻出在第二步中保存的service信息,并通过ApplicationThreadProxy.scheduleCreateService将信息发送给App进程
5.App进程通过ApplicationThread接收消息,并调用ActiivtyThread的sendMessage方法向H发送消息,在H的handleMessage方法会接收消息,之后会调用ActivityThead的handleCreateService方法通过packageinfo拿到加载类的classloader并通过反射创建Service对象,创建完service对象后会紧接着调用其onCreate函数来完成Service的启动。
Service和App在同一个进程中的情况分为三步:
1.app调用Context.startService方法,startService方法又会调用ActivityManagerProxy.startSerivce方法把intent消息发送给AMS
2.AMS检查service是否在AndroidManifest.xml中注册,如果没有注册就抛异常,AMS检查Service所在的进程是否已经启动,如果启动了则将Service启动信息通过ApplicationThreadProxy.scheduleCreateService发送给App进程
3.App进程通过ApplicationThread接收消息并通过ActivityThread.sendMessage发送消息,之后的过程就和上面的第5步是一样的。
绑定过程原理描述:
1.App通过Context.bindService发起绑定,最终会通过ActivityManagerProxy.bindService把service的Intent信息放给AMS
2.AMS检查Service是否在AndroidManifest.xml中进行了注册,如果没有则抛异常。AMS会保存App进程传递过来的信息到ServiceRecord。AMS检查Service所在的进程是否存在,如果不存在就就调用Process.start(android.app.ActivityThread)创建一个新的进程。
3.实例化ActivityThread对象并执行其中的main方法,并对主线程Looper进行初始化。App进程启动后会将ActivityThread通过ActivityManagerProxy发送给AMS
4.AMS接收到ActivityThread后会将ActivityThread包装秤ApplicationThreadProxy,然后通过ApplicationThreadProxy.scheduleBindService向App进程发送消息
5.App进程通过ApplicationThread接收到消息后会调用ActivityThread.sendMessage方法向H发送消息,H通过handleMessage接收到消息后会调用handleBindService对Service进行实例化并调用其onCreate函数。之后会调用Service的onBind函数把Binder发送给AMS