Service启动有两种方式,一种bindService、一种startService。两种启动方式既有相似的地方,也有不一样的,一样的地方都是需要在AMS的管理下启动,都走到ActivityService的bringUpServiceLocked函数。在该函数下,如果要启动的Service是另一个进程的,需要通过startProcessLocked开启新进程,然后在新进程开启ActivityThread线程。
bindService的过程如下:
1. XXXActivity中开始调用bindServer、通知到ActivityManagerService要启动XXXService,于是会先检查这个Service所在的进程是否已经开启,没有去开启,然后把XXXService启动起来,并且调用其onCreate函数;
2. ActivityServiceManager启动了XXXService之后,继续调用XXXService的onBind函数,要求XXXService返回一个IBinder对象给它;
3. ActivityServiceManager从XXXService获得IBinder对象之后,传给XXXActivity。既把这个IBinder对象作为参数传递给XXXActivity内部定义的ServiceConnect对象的onServiceConnected方法;
4. XXXActivity内部定义的ServiceConnection对象的onServiceConnected对象的onServiceConnected函数在得到这个Binder对象之后,就通过getService成员函数获得XXXService接口。
整个过程中,在AIDL机制下作为最重要的就是ServiceDispatcher下的InnerConnection,也即是Stub。连接着XXXActivity所在进程和AMS所在进程的AIDL通信。AMS通过InnerConnection告知XXXActivity服务已启动;通过InnerConnection通知XXXActivity已和服务建立连接,可以获取Service接口了。
startService的过程如下:
1. 在应用中执行startService,通知ActivityManagerService要启动XXXService。若是多进程,则需要在新进程打开这个服务,所以需要创建新进程。
2. 若是在新进程打开,则调用ActivityManagerService,获取新进程中启动XXXService 服务的相关信息;
3. 从ActivityManagerService回到新进程,把相关服务启动起来;
4. 若不在新进程打开,则在当前应用进程中直接开启相关服务;