微信号:baobaospace

介绍:本公众号覆盖Android、iOS、设计模式、敏捷流程等多个领域.本人技术博客:http://www.cnblogs.com/Jax/

写给Android App开发人员看的Android底层知识(5)

2017-05-26 10:45 包建强

对这个系列文章感兴趣的同学,可以加我微信16230091。这个系列一共8篇文章,这里是第5篇,我们讲Service。


(十)Service

Service有两套流程,一套是启动流程,另一套是绑定流程。我们做App开发的同学都应该知道。



1)在新进程启动Service

       我们先看Service启动过程,假设要启动的Service是在一个新的进程中,分为5个阶段:

       1AppAMS发送一个启动Service的消息。

       2AMS检查启动Service的进程是否存在,如果不存在,先把Service信息存下来,然后创建一个新的进程。

       3)新进程启动后,通知AMS说我可以啦。

       4AMS把刚才保存的Service信息发送给新进程

       5)新进程启动Service

 

       我们仔细看一下这5个阶段:

 

1阶段




Activity非常像,仍然是通过AMM/AMP把要启动的Service信息发送给AMS

 

2阶段

       AMS检查Service是否在Manifest中声明了,没声明会直接报错。

 

AMS检查启动Service的进程是否存在,如果不存在,先把Service信息存下来,然后创建一个新的进程。

 

       AMS中,每个Service,都使用ServiceRecord对象来保存。

 

3阶段

       Service所在的新进程启动的过程,就和前面介绍App启动时的过程差不多。

       新进程启动后,也会创建新的ActivityThread,然后把ActivityThread对象通过AMP传递给AMS,告诉AMS,新进程启动成功了。

 

4阶段

       AMS把传进来的ActivityThread对象改造为ApplicationThreadProxy,也就是ATP,通过ATP,把要启动的Service信息发送给新进程。

 

5阶段


新进程通过ApplicationThread接收到AMS的信息,和前面介绍的启动Activity的最后一步相同,借助于ActivityThreadH,执行ServiceonCreate方法。在此期间,为Service创建了Context上下文对象,并与Service相关联。

 

       需要重点关注的是ActivityThreadhandleCreateService方法,



你会发现,这段代码和前面介绍的handleLaunchActivity差不多,都是从PMS中取出包的信息packageInfo,这是一个LoadedApk对象,然后获取它的classloader,反射出来一个类的对象,在这里反射的是Service

       四大组件的逻辑都是如此,所以我们要做插件化,可以在这里做文章,换成插件的classloader,加载插件中的四大组件。

 

       至此,我们在一个新的进程中启动了一个Service

 

      2)启动统一进程的Service

       如果是在当前进程启动这个Service,那么上面的步骤就简化为:

       1AppAMS发送一个启动Service的消息。

       2AMS例行检查,比如Service是否声明了,把ServiceAMS这边注册。AMS发现要启动的Service就是App所在的Service,就通知App启动这个Service

       3App启动Service

 

       我们看到,没有了启动新进程的过程。

 

      3)在同一进程绑定Service

       如果是在当前进程绑定这个Service呢?过程是这样的:

       1AppAMS发送一个绑定Service的消息。

       2AMS例行检查,比如Service是否声明了,把ServiceAMS这边注册。AMS发现要启动的Service就是App所在的Service,就先通知App启动这个Service,然后再通知App,对Service进行绑定操作。

       3App收到AMS1个消息,启动Service

       4App收到AMS2个消息,绑定Service,并把一个Binder对象传给AMS

       5AMS把接收到的Binder对象,发送给App

       6App收到Binder对象,就可以使用了。

 

       你也许会问,都在一个进程,App内部直接使用Binder对象不就好了,其实吧,要考虑不在一个进程的场景,代码又不能写两份,两套逻辑,所以就都放在一起了,即使在同一个进程,也要绕着AMS走一圈。

 

       1阶段:AppAMS发送一个绑定Service的消息。


       4阶段:处理第2个消息



5阶段和第6阶段:

 

这一步是要仔细说的,因为AMSBinder对象传给App,这里没用ATPAPT,而是用到了AIDL来实现,这个AIDL的名字是IServiceConnection



ServiceDispatcherconnect方法,最终会调用ServiceConneciontonServiceConnected方法,这个方法我们就很熟悉了。App开发人员在这个方法中拿到connection,就可以做自己的事情了。

 

 

       好了,关于Service的底层知识,我们就全都介绍完了。当你再去编写一个Service时,是否感觉对这个组件理解的更透彻了呢?

 

       下一篇我们聊一聊BroadcastReceiver

 
包建强的无线技术空间 更多文章 写给Android App开发人员看的Android底层知识(6) 写给Android App开发人员看的Android底层知识(4) 写给Android App开发人员看的Android底层知识(3) 写给Android App开发人员看的Android底层知识(2) 写给Android App开发人员看的Android底层知识(1)
猜您喜欢 不懂如何用Google的人当不好程序员 电子书:《Docker入门实战》 放码过来:阿里Java开发手册正式发布! Algorithm from THE BOOK ops world 2016深圳-Zabbix高级玩法PPT