service启动的过程分析 - l-feng/l-feng.github.io GitHub Wiki

在这里进行解析的是Client启动service的过程,大致的过程我们分为下面四步:

1)Client组件向ActivityManagerService发送一个启动Service组件的进程间的通讯请求

2)ActivityManagerService发现用来运行Service组件的应用进程不存在,因此,他就会

首先将Service组件的信息保存下来,接着在创建一个新的应用程序进程。

3)新的应用程序进程完成启动之后,就会想ActivityManagerService发送一个启动完成的

进程间通讯的请求,以便ActivityManagerService可以执行启动service的组件的操作。

4)ActivityManagerService将第二步保存下来的service组件信息发给第二步创建的应用

程序进程,以便它可以将Service组件启动起来。

这一个过程分为19步,接下来就分析每一步多应的函数

Client.onCreate()-------->ContextWrapper.startService()----->ContextImpl.startService()

---->ActivityManagerProxy.startservice()----->ActivityManagerService.startService()--->

ActivityManagerService.startServiceLocked()-------->ActivityManagerService.bringUpServiceLocked()

------->ActivityManagerService.startProcessLocked()-----ActivityThread.main()----->

ActivityManagerProxy.attachApplication---->ActivityManagerService.attachApplication()------

ActivityManagerservice.attachApplicationLocked()---->ActivityManagerService.realStartServiceLocked()----

ApplicationThreadProxy.scheduleCreateService()--->ApplicationThread.scheduleCreateService()---

AcyivityThread.queueOrSendMessager---->H.handleMessage--->ActivityThread.handleCreateService(0----->

Service.onCreate()

1)Client.onCreate():

首先会调用getMemoryService()来获得内存访问服务MemoryService的一个代理对象,如果MemoryService服务没有起来,

则接下来调用ContenxtWrapper.startServic将其启动起来。

IMemoryService ms=getMemoryService();

If(ms==null){

startService(new Intent(“shy.lunatic.ashmem.service”));

}else{

}

2)ContextWrapper.startService()

每一个activity组件在启动时,ActivityThread类都会为它创建一个ContextImpl对象,用来描述它运行的上下文。

这个对象就保存在mBase中,在该方法中,实际上就是调用ContextImpl中的startService来启动service组件。

Public CompomentName startService(Intent service){

 Return mBase.startService(service);

}

3)ContextImpl.startService()

首先通过调用ActivityManagernative类的静态成员函数getDefault来获得ActivityManagerService的一个代理对象,

接着在调用这个代理对象的成员函数startService来请求ActivityManagerService启动service组件

Public ComponentName startService(Intent Service){

Try{

ComponentName

cn=ActivityManagerNative.getDefault().startService(mMainThread.getApplicationThread(),service,

servce.resolveTypeIfNeed(getContentResolver));

........

Return cn;

}catch(RemoteException e){

Return null; }

}

4)ActivityManagerProxy.startservice()

首先将前面传进来的参数写入到Pacel对象的data对象中,接着在通过ActivityManagerProxy类内部的一个Binder

代理对象mRemote向ActivityManagerService发送一个类型为STATE_SERVICE_TRANSACTION的进程间的通信请求。

以上的四步都是在内存访问服务中完成的,接下来的5到8步是在AMS中完成的,主要是处理进程间的通信请求STATE_SERVICE_TRANSACTION

5)ActivityManagerService.startService()

在该函数中主要调用的是startServiceLocked()函数来进行进一步处理类型为STATE_SERVICE_TRANSACTION的通信间的请求的。

compoentName res= startServiceLocked(caller,service,resolvedtype,callingPid,callingUid);

6)ActivityManagerService.startServiceLocked()

Componentname startservicelocked(IApplicationThread caller,intent service,String resolvedtype,int callingPid,int

callingUid ){

Synchronized(this){

ServicelookupResult res=retrieveServiceLocked(service,resolvedType,callingPid,callingUid);

.....

ServiceRecord r= res.record;

.....

If(!bringUpServicelocked(r,service.getFlags(),false){

Return new CompoentName(“!”,”service process is bad”);

}

Return r;

}

}

...

} 在AMS中,每一个service组件都使用一个serviceRecord对象来描述。

首先会调用retrieveServiceLocked(service,resolvedType,callingPid,callingUid)来查找是否有

serviceRecoed与service对应,如果不存在,则创建一个对象信息serviceRecord。然后封住成为serviceLookupResult(

)对象返回给调用者。,之后调用bringUpServicelocked()来启动serviceRecord组件对象r所描述的service信息。

7)ActivityManagerService.bringUpServiceLocked()

  1:首先获得serviceRecord对象r描述的service组件的android:process的属性保存在appname中

  2:根据r所描述的用户ID以及android:process的属性在AMS中查找是否已经存在一个对应的processRecord对象app

  3;判断app是否存在,如果存在,则调用realstartServiceLocked启动这个service组件,如果没有存在,则调用

startprocesslocked启动一个service组件。

  4:sercive组件信息保存在AMS中,等待service组件启动。

8)ActivityManagerService.startProcessLocked()

 主要是调用process类的静态成员函数start来创建一个新的应用程序,这个新创建的额应用程序进程以ActivityThread

类的静态成员函数main()入口。

以上的四步是在AMS中进行的,接下来的9,10步是在应用程序中进行的,主要是初始化新创建的应用程序进程。

9)ActivityThread.main()

在新创建的应用程序进程中吗创建一个ActivityThread对象和一个ApplicationThread对象

10)ActivityManagerProxy.attachApplication、

向AMS发送一个ATTACH_APPLICATION_TRANSACTION的进程间通信请求,以及将前面创建的一个applicationThread对象传

递给AMS,以便于AMS可以和这个新创建的应用程序进程执行Binder进程间通信。

以上的两步是在应用进程中创建的,接下里的11-14步是在AMS中执行的,主要是处理ATTACH_APPLICATION_TRANSACTION的进程

间通信请求。

11)ActivityManagerService.attachApplication()

主要是调用AMS类的成员函数attachApplicationlocked来处理类型为ATTACH_APPLICATION_TRANSACTION进程间的通信请求,

用来启动执行service组件的操作。

12)ActivityManagerservice.attachApplicationLocked()

1:通过pid将processRecord对象取回来,保存在app中。

2:为ApplicationThread创建一个代理对象,之后AMS可以通过这个代理对象来和新创建的应用程序进行通信。

3:检查位于activity组件栈顶的activity组件是否需要在新创建的应用程序进程中启动。如果是,调用realStartActivityLocked

将这个activity组件启动起来。如果已经启动,但是窗口没有显示出来,就调用ensureActivitiesVisibleLocked将窗口显示出来。

总结下,当一个应用程序启动完成之后,AMS会优先处理需要在他里面启动或者显示的activity组件,然后在处理它里面的service组件,

这主要是因为activity组件需要和用户交互的,service则不需要。

4: 检查mPendingService中的service是否需要在新创建的应用程序中启动,如果需要,则在mPendingservicezhogn 删除,在调用

realserviceLocked将它重新启动。

5:在7步中保存的serviceRecord对象保存在mpendingService中,它在等待processRecord对象app所描述的应用程序启动,这个时

候调用AMS的realStartActivityLocked启动它

13)ActivityManagerService.realStartServiceLocked()

1:设置r的app为Processrecord对象的app,表示serviceRecord对象r描述的service组件是在processRecord对象所描述的应用

程序进程中启动的

2: 调用scheduleCreateService来请求新创建的应用程序进程将serviceRecord对象r所描述的service组件启动起来

14)ApplicationThread.scheduleCreateService()

通过ApplicationThreadProxy类内部一个Binder代理对象mRemte向新创建的应用进程发送一个类型为

SCHEDULE_CREATE_SERVICE_TRANSACTION的进程间通信请求。

以上四步在AMS中创建的,接下来的15--19步是在应用进程中进行的。

15)ApplicationThread.scheduleCreateService()

主要处理SCHEDULE_CREATE_SERVICE_TRANSACTION的进程间的通讯请求,

1:首先启动service组件的信息封装成一个CreateServiceData对象

2: 接着调用ActivityThread的成员函数queueOrSendMessage将这个CreateServiceData对象封装成一个类型为

CREATE_SERVICE的消息,以便于可以将它发送到新创建的应用程序中进程的主线程的消息队列中。

16)AcyivityThread.queueOrSendMessager

调用ActivityThread中的sendMessage将这个消息发送到新创建的应用程序进程的主线程的消息对垒中,这个消息最终在

ActivityThread类的成员函数handleMessage中进行处理。

  1. H.handleMessage

首先将Message对象msg的成员变量转换成一个CreateServiceData对象,里面包含了要启动Service的组件信息,接着

调用ActivityThread类的成员函数HandleCreateService将这个service启动起来

18)ActivityThread.handleCreateService(0

1:使用getPackageInfoNoCheck来获得一个用来描述即将要启动service组件所在的应用程序的loadApk对象。

并且保存在packageInfo中。可以通过loadApk获得应用程序的资源

2:通过getClassloader来获得类加载器,将Service组件加载到内存中,并且创建实例,保存service对象service。

3:初始还ContextImpl,用来作为描述所创建的service的上下文信息。通过它可以访问到应用程序资源,以及启动其他的

应用程序的组件。

4:创建aplication对象app。用来描述service所属的应用程序。

5 : 调用Oncreare函数,用户执行初始化的操作。

6:将service对象sercvice保存在ActivityThread类成员变量mservice

  1. Service.onCreate()

主要是用来启动一个内存访问服务MemoryService中,并且注册到ServiceManager中。