`

Android系统在新进程中启动自定义服务过程(startService)的原理分析

 
阅读更多

在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。

在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder进程间通信机制有一定的了解,具体可以参考前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。

关于startService的具体用法,可以参考前面Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划一文中用到的实例,它是Activity类的一个成员函数:

view plain
  1. packageshy.luo.ashmem;
  2. ......
  3. publicclassClientextendsActivityimplementsOnClickListener{
  4. ......
  5. IMemoryServicememoryService=null;
  6. ......
  7. @Override
  8. publicvoidonCreate(BundlesavedInstanceState){
  9. ......
  10. IMemoryServicems=getMemoryService();
  11. if(ms==null){
  12. startService(newIntent("shy.luo.ashmem.server"));
  13. }else{
  14. Log.i(LOG_TAG,"MemoryServicehasstarted.");
  15. }
  16. ......
  17. Log.i(LOG_TAG,"ClientActivityCreated.");
  18. }
  19. ......
  20. }

这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:

view plain
  1. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  2. package="shy.luo.ashmem"
  3. android:sharedUserId="android.uid.system"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  7. ......
  8. <service
  9. android:enabled="true"
  10. android:name=".Server"
  11. android:process=".Server">
  12. <intent-filter>
  13. <actionandroid:name="shy.luo.ashmem.server"/>
  14. <categoryandroid:name="android.intent.category.DEFAULT"/>
  15. </intent-filter>
  16. </service>
  17. </application>
  18. </manifest>
这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:
view plain
  1. startService(newIntent("shy.luo.ashmem.server"));
就表示要在一个新的进程中启动shy.luo.ashmem.Server这个服务类,它必须继承于Android平台提供的Service类:
view plain
  1. packageshy.luo.ashmem;
  2. ......
  3. publicclassServerextendsService{
  4. ......
  5. @Override
  6. publicIBinderonBind(Intentintent){
  7. returnnull;
  8. }
  9. @Override
  10. publicvoidonCreate(){
  11. ......
  12. }
  13. ......
  14. }
下面,我们来看看Activity类中的startService成员函数是如何实现的。

先来看看Activity的类图:


从图中可以看出,Activity继承了ContextWrapper类,而在ContextWrapper类中,实现了startService函数。在ContextWrapper类中,有一个成员变量mBase,它是一个ContextImpl实例,而ContextImpl类和ContextWrapper类一样继承于Context类,ContextWrapper类的startService函数最终过调用ContextImpl类的startService函数来实现。这种类设计方法在设计模式里面,就称之为装饰模式(Decorator),或者包装模式(Wrapper)。

在ContextImpl类的startService类,最终又调用了ActivityManagerProxy类的startService来实现启动服务的操作,看到这里的Proxy关键字,回忆一下前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析这篇文章,就会知道ActivityManagerProxy是一个Binder对象的远程接口了,而这个Binder对象就是我们前面所说的ActivityManagerService了。

这个ActivityManagerService类实现在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中,它是Binder进程间通信机制中的Server角色,它是随机启动的。随机启动的Server是在frameworks/base/services/java/com/android/server/SystemServer.java文件里面进行启动的,我们来看一下ActivityManagerService启动相关的代码:

view plain
  1. classServerThreadextendsThread{
  2. ......
  3. @Override
  4. publicvoidrun(){
  5. ......
  6. //Criticalservices...
  7. try{
  8. ......
  9. context=ActivityManagerService.main(factoryTest);
  10. ......
  11. ActivityManagerService.setSystemProcess();
  12. ......
  13. }catch(RuntimeExceptione){
  14. Slog.e("System","Failurestartingcoreservice",e);
  15. }
  16. ......
  17. }
  18. ......
  19. }
首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService实例,然后通过调用ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程ServiceManager中去:
view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. staticActivityManagerServicemSelf;
  5. ......
  6. publicstaticvoidsetSystemProcess(){
  7. try{
  8. ActivityManagerServicem=mSelf;
  9. ServiceManager.addService("activity",m);
  10. ......
  11. }catch(PackageManager.NameNotFoundExceptione){
  12. ......
  13. }
  14. }
  15. ......
  16. publicstaticfinalContextmain(intfactoryTest){
  17. ......
  18. ActivityManagerServicem=thr.mService;
  19. mSelf=m;
  20. ......
  21. }
  22. }
这样,ActivityManagerService就启动起来了。

回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

view plain
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
  5. StringresolvedType)throwsRemoteException
  6. {
  7. Parceldata=Parcel.obtain();
  8. Parcelreply=Parcel.obtain();
  9. data.writeInterfaceToken(IActivityManager.descriptor);
  10. data.writeStrongBinder(caller!=null?caller.asBinder():null);
  11. service.writeToParcel(data,0);
  12. data.writeString(resolvedType);
  13. mRemote.transact(START_SERVICE_TRANSACTION,data,reply,0);
  14. reply.readException();
  15. ComponentNameres=ComponentName.readFromParcel(reply);
  16. data.recycle();
  17. reply.recycle();
  18. returnres;
  19. }
  20. ......
  21. }
参数service是一个Intent实例,它里面指定了要启动的服务的名称,就是前面我们所说的“shy.luo.ashmem.server”了。

参数caller是一个IApplicationThread实例,它是一个在主进程创建的一个Binder对象。在Android应用程序中,每一个进程都用一个ActivityThread实例来表示,而在ActivityThread类中,有一个成员变量mAppThread,它是一个ApplicationThread实例,实现了IApplicationThread接口,它的作用是用来辅助ActivityThread类来执行一些操作,这个我们在后面会看到它是如何用来启动服务的。

参数resolvedType是一个字符串,它表示service这个Intent的MIME类型,它是在解析Intent时用到的。在这个例子中,我们没有指定这个Intent 的MIME类型,因此,这个参数为null。

ActivityManagerProxy类的startService函数把这三个参数写入到data本地变量去,接着通过mRemote.transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒正在等待Client请求的ActivityManagerService进程,最后进入到ActivityManagerService的startService函数中。

ActivityManagerService的startService函数的处理流程如下图所示:


点击查看大图

在这个序列图中,一共有20个步骤,下面说明每一步。

Step 1. ActivityManagerService.startService

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
  5. StringresolvedType){
  6. //Refusepossibleleakedfiledescriptors
  7. if(service!=null&&service.hasFileDescriptors()==true){
  8. thrownewIllegalArgumentException("FiledescriptorspassedinIntent");
  9. }
  10. synchronized(this){
  11. finalintcallingPid=Binder.getCallingPid();
  12. finalintcallingUid=Binder.getCallingUid();
  13. finallongorigId=Binder.clearCallingIdentity();
  14. ComponentNameres=startServiceLocked(caller,service,
  15. resolvedType,callingPid,callingUid);
  16. Binder.restoreCallingIdentity(origId);
  17. returnres;
  18. }
  19. }
  20. ......
  21. }
这里的参数caller、service和resolvedType分别对应ActivityManagerProxy.startService传进来的三个参数。

Step 2.ActivityManagerService.startServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. ComponentNamestartServiceLocked(IApplicationThreadcaller,
  5. Intentservice,StringresolvedType,
  6. intcallingPid,intcallingUid){
  7. synchronized(this){
  8. ......
  9. ServiceLookupResultres=
  10. retrieveServiceLocked(service,resolvedType,
  11. callingPid,callingUid);
  12. ......
  13. ServiceRecordr=res.record;
  14. ......
  15. if(!bringUpServiceLocked(r,service.getFlags(),false)){
  16. returnnewComponentName("!","Serviceprocessisbad");
  17. }
  18. returnr.name;
  19. }
  20. }
  21. ......
  22. }
函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,然后继续调用bringUpServiceLocked进一步处理。

Step 3. ActivityManagerService.bringUpServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalbooleanbringUpServiceLocked(ServiceRecordr,
  5. intintentFlags,booleanwhileRestarting){
  6. ......
  7. finalStringappName=r.processName;
  8. ......
  9. //Notrunning--getitstarted,andenqueuethisservicerecord
  10. //tobeexecutedwhentheappcomesup.
  11. if(startProcessLocked(appName,r.appInfo,true,intentFlags,
  12. "service",r.name,false)==null){
  13. ......
  14. returnfalse;
  15. }
  16. if(!mPendingServices.contains(r)){
  17. mPendingServices.add(r);
  18. }
  19. returntrue;
  20. }
  21. ......
  22. }
这里的appName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,即“.Server”。

接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。

Step 4.ActivityManagerService.startProcessLocked

这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalvoidstartProcessLocked(ProcessRecordapp,
  5. StringhostingType,StringhostingNameStr){
  6. ......
  7. try{
  8. ......
  9. intpid=Process.start("android.app.ActivityThread",
  10. mSimpleProcessManagement?app.processName:null,uid,uid,
  11. gids,debugFlags,null);
  12. ......
  13. if(pid==0||pid==MY_PID){
  14. ......
  15. }elseif(pid>0){
  16. app.pid=pid;
  17. app.removed=false;
  18. synchronized(mPidsSelfLocked){
  19. this.mPidsSelfLocked.put(pid,app);
  20. ......
  21. }
  22. }else{
  23. ......
  24. }
  25. }catch(RuntimeExceptione){
  26. ......
  27. }
  28. }
  29. ......
  30. }
这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中,后面会用到。

Step 5. Process.start

这个函数定义在frameworks/base/core/java/android/os/Process.java文件中,这个函数我们就不看了,有兴趣的读者可以自己研究一下。在这个场景中,它就是新建一个进程,然后导入android.app.ActivityThread这个类,然后执行它的main函数。

Step 6.ActivityThread.main
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. publicstaticfinalvoidmain(String[]args){
  4. ......
  5. Looper.prepareMainLooper();
  6. ......
  7. ActivityThreadthread=newActivityThread();
  8. thread.attach(false);
  9. ......
  10. Looper.loop();
  11. ......
  12. thread.detach();
  13. ......
  14. }
  15. }
注意,执行到这里的时候,已经是在上一步创建的新进程里面了,即这里的进程是用来启动服务的,原来的主进程已经完成了它的命令,返回了。

前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。

Step 7.ActivityThread.attach

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalvoidattach(booleansystem){
  4. ......
  5. if(!system){
  6. ......
  7. IActivityManagermgr=ActivityManagerNative.getDefault();
  8. try{
  9. mgr.attachApplication(mAppThread);
  10. }catch(RemoteExceptionex){
  11. }
  12. }else{
  13. ......
  14. }
  15. ......
  16. }
  17. ......
  18. }
从Step 6中,这里传进来的参数system为false。成员变量mAppThread是一个ApplicationThread实例,我们在前面已经描述过这个实例的作用,它是用来辅助ActivityThread来执行一些操作的。

调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。

Step 8.ActivityManagerProxy.attachApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

view plain
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. publicvoidattachApplication(IApplicationThreadapp)throwsRemoteException
  5. {
  6. Parceldata=Parcel.obtain();
  7. Parcelreply=Parcel.obtain();
  8. data.writeInterfaceToken(IActivityManager.descriptor);
  9. data.writeStrongBinder(app.asBinder());
  10. mRemote.transact(ATTACH_APPLICATION_TRANSACTION,data,reply,0);
  11. reply.readException();
  12. data.recycle();
  13. reply.recycle();
  14. }
  15. ......
  16. }

这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。

Step 9. ActivityManagerService.attachApplication

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. publicfinalvoidattachApplication(IApplicationThreadthread)
  5. {
  6. synchronized(this){
  7. intcallingPid=Binder.getCallingPid();
  8. finallongorigId=Binder.clearCallingIdentity();
  9. attachApplicationLocked(thread,callingPid);
  10. Binder.restoreCallingIdentity(origId);
  11. }
  12. }
  13. ......
  14. }
这里通过调用attachApplicationLocked函数进一步处理。

Step 10.ActivityManagerService.attachApplicationLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalbooleanattachApplicationLocked(IApplicationThreadthread,
  5. intpid){
  6. //Findtheapplicationrecordthatisbeingattached...eithervia
  7. //thepidifwearerunninginmultipleprocesses,orjustpullthe
  8. //nextapprecordifweareemulatingprocesswithanonymousthreads.
  9. ProcessRecordapp;
  10. if(pid!=MY_PID&&pid>=0){
  11. synchronized(mPidsSelfLocked){
  12. app=mPidsSelfLocked.get(pid);
  13. }
  14. }elseif(mStartingProcesses.size()>0){
  15. app=mStartingProcesses.remove(0);
  16. app.setPid(pid);
  17. }else{
  18. app=null;
  19. }
  20. ......
  21. StringprocessName=app.processName;
  22. ......
  23. app.thread=thread;
  24. ......
  25. booleanbadApp=false;
  26. ......
  27. //Findanyservicesthatshouldberunninginthisprocess...
  28. if(!badApp&&mPendingServices.size()>0){
  29. ServiceRecordsr=null;
  30. try{
  31. for(inti=0;i<mPendingServices.size();i++){
  32. sr=mPendingServices.get(i);
  33. if(app.info.uid!=sr.appInfo.uid
  34. ||!processName.equals(sr.processName)){
  35. continue;
  36. }
  37. mPendingServices.remove(i);
  38. i--;
  39. realStartServiceLocked(sr,app);
  40. didSomething=true;
  41. }
  42. }catch(Exceptione){
  43. ......
  44. }
  45. }
  46. ......
  47. returntrue;
  48. }
  49. ......
  50. }
回忆一下在上面的Step 4中,以新进程的pid值作为key值保存了一个ProcessRecord在mPidsSelfLocked列表中,这里先把它取出来,存放在本地变量app中,并且将app.processName保存在本地变量processName中。

再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。

Step 11.ActivityManagerService.realStartServiceLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. privatefinalvoidrealStartServiceLocked(ServiceRecordr,
  5. ProcessRecordapp)throwsRemoteException{
  6. ......
  7. r.app=app;
  8. ......
  9. try{
  10. ......
  11. app.thread.scheduleCreateService(r,r.serviceInfo);
  12. ......
  13. }finally{
  14. ......
  15. }
  16. ......
  17. }
  18. ......
  19. }

这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。

Step 12. ApplicationThreadProxy.scheduleCreateService

这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

view plain
  1. classApplicationThreadProxyimplementsIApplicationThread{
  2. ......
  3. publicfinalvoidscheduleCreateService(IBindertoken,ServiceInfoinfo)
  4. throwsRemoteException{
  5. Parceldata=Parcel.obtain();
  6. data.writeInterfaceToken(IApplicationThread.descriptor);
  7. data.writeStrongBinder(token);
  8. info.writeToParcel(data,0);
  9. mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION,data,null,
  10. IBinder.FLAG_ONEWAY);
  11. data.recycle();
  12. }
  13. ......
  14. }

这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。

Step 13.ApplicationThread.scheduleCreateService

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalclassApplicationThreadextendsApplicationThreadNative{
  4. ......
  5. publicfinalvoidscheduleCreateService(IBindertoken,
  6. ServiceInfoinfo){
  7. CreateServiceDatas=newCreateServiceData();
  8. s.token=token;
  9. s.info=info;
  10. queueOrSendMessage(H.CREATE_SERVICE,s);
  11. }
  12. ......
  13. }
  14. ......
  15. }
这里调用ActivityThread的queueOrSendMessage将一个CreateServiceData数据放到消息队列中去,并且分开这个消息。注意,这里已经是在上面Step 4创建的新进程中执行了。

Step 14.ActivityThread.queueOrSendMessage

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalvoidqueueOrSendMessage(intwhat,Objectobj){
  4. queueOrSendMessage(what,obj,0,0);
  5. }
  6. privatefinalvoidqueueOrSendMessage(intwhat,Objectobj,intarg1,intarg2){
  7. synchronized(this){
  8. ......
  9. Messagemsg=Message.obtain();
  10. msg.what=what;
  11. msg.obj=obj;
  12. msg.arg1=arg1;
  13. msg.arg2=arg2;
  14. mH.sendMessage(msg);
  15. }
  16. }
  17. ......
  18. }

这里调用成员变量mH的sendMessage函数进行消息分发。这里的mH的类型为H,它继承于Handler类。

Step 15. H.sendMessage

这个函数继承于Handle类的sendMessage函数中,定义在frameworks/base/core/java/android/os/Handler.java文件中。这个函数我们就不看了,有兴趣的读者可以自己研究一下。消息分发以后,就进入到H.handleMessage函数进行处理了。

Step 16. H.handleMessage

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalclassHextendsHandler{
  4. ......
  5. publicvoidhandleMessage(Messagemsg){
  6. ......
  7. switch(msg.what){
  8. ......
  9. caseCREATE_SERVICE:
  10. handleCreateService((CreateServiceData)msg.obj);
  11. break;
  12. ......
  13. }
  14. ......
  15. }
  16. ......
  17. }
  18. ......
  19. }
这里要处理的消息是CREATE_SERVICE,它调用ActivityThread类的handleCreateService成员函数进一步处理。

Step 17.ActivityThread.handleCreateService

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalvoidhandleCreateService(CreateServiceDatadata){
  4. //Ifwearegettingreadytogcaftergoingtothebackground,well
  5. //wearebackactivesoskipit.
  6. unscheduleGcIdler();
  7. LoadedApkpackageInfo=getPackageInfoNoCheck(
  8. data.info.applicationInfo);
  9. Serviceservice=null;
  10. try{
  11. java.lang.ClassLoadercl=packageInfo.getClassLoader();
  12. service=(Service)cl.loadClass(data.info.name).newInstance();
  13. }catch(Exceptione){
  14. if(!mInstrumentation.onException(service,e)){
  15. thrownewRuntimeException(
  16. "Unabletoinstantiateservice"+data.info.name
  17. +":"+e.toString(),e);
  18. }
  19. }
  20. try{
  21. if(localLOGV)Slog.v(TAG,"Creatingservice"+data.info.name);
  22. ContextImplcontext=newContextImpl();
  23. context.init(packageInfo,null,this);
  24. Applicationapp=packageInfo.makeApplication(false,mInstrumentation);
  25. context.setOuterContext(service);
  26. service.attach(context,this,data.info.name,data.token,app,
  27. ActivityManagerNative.getDefault());
  28. service.onCreate();
  29. mServices.put(data.token,service);
  30. try{
  31. ActivityManagerNative.getDefault().serviceDoneExecuting(
  32. data.token,0,0,0);
  33. }catch(RemoteExceptione){
  34. //nothingtodo.
  35. }
  36. }catch(Exceptione){
  37. if(!mInstrumentation.onException(service,e)){
  38. thrownewRuntimeException(
  39. "Unabletocreateservice"+data.info.name
  40. +":"+e.toString(),e);
  41. }
  42. }
  43. }
  44. ......
  45. }
这里的data.info.name就是自定义的服务类shy.luo.ashmem.Server了。

Step 18. ClassLoader.loadClass

这一步实现在上面的ActivityThread.handleCreateService函数中:

view plain
  1. java.lang.ClassLoadercl=packageInfo.getClassLoader();
  2. service=(Service)cl.loadClass(data.info.name).newInstance();
Step 19. Obtain Service

这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。

Step 20. Service.onCreate

这一步继续实现在上面的ActivityThread.handleCreateService函数中:

view plain
  1. service.onCreate();
因为这里的service实际上是一个shy.luo.ashmem.Server类实例,因此,这里就是执行shy.luo.ashmem.Server类的onCreate函数了:
view plain
  1. publicclassServerextendsService{
  2. ......
  3. @Override
  4. publicvoidonCreate(){
  5. ......
  6. }
  7. ......
  8. }
至此,这个自定义的服务就启动起来了。

这样,Android系统在新进程中启动服务的过程就分析完成了,虽然很复杂,但是条理很清晰。它通过三次Binder进程间通信完成了服务的启动过程,分别是:

一. Step 1至Step 7,从主进程调用到ActivityManagerService进程中,完成新进程的创建;

二. Step 8至Step 11,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;

三. Step 12至Step 20,从ActivityManagerService进程又回到新进程中,最终将服务启动起来。

学习完Android系统在新进程中启动服务的过程后,希望读者对Android系统的Service有一个深刻的理解。在编写Android应用程序的时候,尽量把一些计算型的逻辑以Service在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。


在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。

在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder进程间通信机制有一定的了解,具体可以参考前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。

关于startService的具体用法,可以参考前面Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划一文中用到的实例,它是Activity类的一个成员函数:

view plain
  1. packageshy.luo.ashmem;
  2. ......
  3. publicclassClientextendsActivityimplementsOnClickListener{
  4. ......
  5. IMemoryServicememoryService=null;
  6. ......
  7. @Override
  8. publicvoidonCreate(BundlesavedInstanceState){
  9. ......
  10. IMemoryServicems=getMemoryService();
  11. if(ms==null){
  12. startService(newIntent("shy.luo.ashmem.server"));
  13. }else{
  14. Log.i(LOG_TAG,"MemoryServicehasstarted.");
  15. }
  16. ......
  17. Log.i(LOG_TAG,"ClientActivityCreated.");
  18. }
  19. ......
  20. }

这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:

view plain
  1. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  2. package="shy.luo.ashmem"
  3. android:sharedUserId="android.uid.system"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  7. ......
  8. <service
  9. android:enabled="true"
  10. android:name=".Server"
  11. android:process=".Server">
  12. <intent-filter>
  13. <actionandroid:name="shy.luo.ashmem.server"/>
  14. <categoryandroid:name="android.intent.category.DEFAULT"/>
  15. </intent-filter>
  16. </service>
  17. </application>
  18. </manifest>
这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:
view plain
  1. startService(newIntent("shy.luo.ashmem.server"));
就表示要在一个新的进程中启动shy.luo.ashmem.Server这个服务类,它必须继承于Android平台提供的Service类:
view plain
  1. packageshy.luo.ashmem;
  2. ......
  3. publicclassServerextendsService{
  4. ......
  5. @Override
  6. publicIBinderonBind(Intentintent){
  7. returnnull;
  8. }
  9. @Override
  10. publicvoidonCreate(){
  11. ......
  12. }
  13. ......
  14. }
下面,我们来看看Activity类中的startService成员函数是如何实现的。

先来看看Activity的类图:


从图中可以看出,Activity继承了ContextWrapper类,而在ContextWrapper类中,实现了startService函数。在ContextWrapper类中,有一个成员变量mBase,它是一个ContextImpl实例,而ContextImpl类和ContextWrapper类一样继承于Context类,ContextWrapper类的startService函数最终过调用ContextImpl类的startService函数来实现。这种类设计方法在设计模式里面,就称之为装饰模式(Decorator),或者包装模式(Wrapper)。

在ContextImpl类的startService类,最终又调用了ActivityManagerProxy类的startService来实现启动服务的操作,看到这里的Proxy关键字,回忆一下前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析这篇文章,就会知道ActivityManagerProxy是一个Binder对象的远程接口了,而这个Binder对象就是我们前面所说的ActivityManagerService了。

这个ActivityManagerService类实现在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中,它是Binder进程间通信机制中的Server角色,它是随机启动的。随机启动的Server是在frameworks/base/services/java/com/android/server/SystemServer.java文件里面进行启动的,我们来看一下ActivityManagerService启动相关的代码:

view plain
  1. classServerThreadextendsThread{
  2. ......
  3. @Override
  4. publicvoidrun(){
  5. ......
  6. //Criticalservices...
  7. try{
  8. ......
  9. context=ActivityManagerService.main(factoryTest);
  10. ......
  11. ActivityManagerService.setSystemProcess();
  12. ......
  13. }catch(RuntimeExceptione){
  14. Slog.e("System","Failurestartingcoreservice",e);
  15. }
  16. ......
  17. }
  18. ......
  19. }
首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService实例,然后通过调用ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程ServiceManager中去:
view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. staticActivityManagerServicemSelf;
  5. ......
  6. publicstaticvoidsetSystemProcess(){
  7. try{
  8. ActivityManagerServicem=mSelf;
  9. ServiceManager.addService("activity",m);
  10. ......
  11. }catch(PackageManager.NameNotFoundExceptione){
  12. ......
  13. }
  14. }
  15. ......
  16. publicstaticfinalContextmain(intfactoryTest){
  17. ......
  18. ActivityManagerServicem=thr.mService;
  19. mSelf=m;
  20. ......
  21. }
  22. }
这样,ActivityManagerService就启动起来了。

回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

view plain
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
  5. StringresolvedType)throwsRemoteException
  6. {
  7. Parceldata=Parcel.obtain();
  8. Parcelreply=Parcel.obtain();
  9. data.writeInterfaceToken(IActivityManager.descriptor);
  10. data.writeStrongBinder(caller!=null?caller.asBinder():null);
  11. service.writeToParcel(data,0);
  12. data.writeString(resolvedType);
  13. mRemote.transact(START_SERVICE_TRANSACTION,data,reply,0);
  14. reply.readException();
  15. ComponentNameres=ComponentName.readFromParcel(reply);
  16. data.recycle();
  17. reply.recycle();
  18. returnres;
  19. }
  20. ......
  21. }
参数service是一个Intent实例,它里面指定了要启动的服务的名称,就是前面我们所说的“shy.luo.ashmem.server”了。

参数caller是一个IApplicationThread实例,它是一个在主进程创建的一个Binder对象。在Android应用程序中,每一个进程都用一个ActivityThread实例来表示,而在ActivityThread类中,有一个成员变量mAppThread,它是一个ApplicationThread实例,实现了IApplicationThread接口,它的作用是用来辅助ActivityThread类来执行一些操作,这个我们在后面会看到它是如何用来启动服务的。

参数resolvedType是一个字符串,它表示service这个Intent的MIME类型,它是在解析Intent时用到的。在这个例子中,我们没有指定这个Intent 的MIME类型,因此,这个参数为null。

ActivityManagerProxy类的startService函数把这三个参数写入到data本地变量去,接着通过mRemote.transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒正在等待Client请求的ActivityManagerService进程,最后进入到ActivityManagerService的startService函数中。

ActivityManagerService的startService函数的处理流程如下图所示:


点击查看大图

在这个序列图中,一共有20个步骤,下面说明每一步。

Step 1. ActivityManagerService.startService

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
  5. StringresolvedType){
  6. //Refusepossibleleakedfiledescriptors
  7. if(service!=null&&service.hasFileDescriptors()==true){
  8. thrownewIllegalArgumentException("FiledescriptorspassedinIntent");
  9. }
  10. synchronized(this){
  11. finalintcallingPid=Binder.getCallingPid();
  12. finalintcallingUid=Binder.getCallingUid();
  13. finallongorigId=Binder.clearCallingIdentity();
  14. ComponentNameres=startServiceLocked(caller,service,
  15. resolvedType,callingPid,callingUid);
  16. Binder.restoreCallingIdentity(origId);
  17. returnres;
  18. }
  19. }
  20. ......
  21. }
这里的参数caller、service和resolvedType分别对应ActivityManagerProxy.startService传进来的三个参数。

Step 2.ActivityManagerService.startServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. ComponentNamestartServiceLocked(IApplicationThreadcaller,
  5. Intentservice,StringresolvedType,
  6. intcallingPid,intcallingUid){
  7. synchronized(this){
  8. ......
  9. ServiceLookupResultres=
  10. retrieveServiceLocked(service,resolvedType,
  11. callingPid,callingUid);
  12. ......
  13. ServiceRecordr=res.record;
  14. ......
  15. if(!bringUpServiceLocked(r,service.getFlags(),false)){
  16. returnnewComponentName("!","Serviceprocessisbad");
  17. }
  18. returnr.name;
  19. }
  20. }
  21. ......
  22. }
函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,然后继续调用bringUpServiceLocked进一步处理。

Step 3. ActivityManagerService.bringUpServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalbooleanbringUpServiceLocked(ServiceRecordr,
  5. intintentFlags,booleanwhileRestarting){
  6. ......
  7. finalStringappName=r.processName;
  8. ......
  9. //Notrunning--getitstarted,andenqueuethisservicerecord
  10. //tobeexecutedwhentheappcomesup.
  11. if(startProcessLocked(appName,r.appInfo,true,intentFlags,
  12. "service",r.name,false)==null){
  13. ......
  14. returnfalse;
  15. }
  16. if(!mPendingServices.contains(r)){
  17. mPendingServices.add(r);
  18. }
  19. returntrue;
  20. }
  21. ......
  22. }
这里的appName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,即“.Server”。

接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。

Step 4.ActivityManagerService.startProcessLocked

这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalvoidstartProcessLocked(ProcessRecordapp,
  5. StringhostingType,StringhostingNameStr){
  6. ......
  7. try{
  8. ......
  9. intpid=Process.start("android.app.ActivityThread",
  10. mSimpleProcessManagement?app.processName:null,uid,uid,
  11. gids,debugFlags,null);
  12. ......
  13. if(pid==0||pid==MY_PID){
  14. ......
  15. }elseif(pid>0){
  16. app.pid=pid;
  17. app.removed=false;
  18. synchronized(mPidsSelfLocked){
  19. this.mPidsSelfLocked.put(pid,app);
  20. ......
  21. }
  22. }else{
  23. ......
  24. }
  25. }catch(RuntimeExceptione){
  26. ......
  27. }
  28. }
  29. ......
  30. }
这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中,后面会用到。

Step 5. Process.start

这个函数定义在frameworks/base/core/java/android/os/Process.java文件中,这个函数我们就不看了,有兴趣的读者可以自己研究一下。在这个场景中,它就是新建一个进程,然后导入android.app.ActivityThread这个类,然后执行它的main函数。

Step 6.ActivityThread.main
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. publicstaticfinalvoidmain(String[]args){
  4. ......
  5. Looper.prepareMainLooper();
  6. ......
  7. ActivityThreadthread=newActivityThread();
  8. thread.attach(false);
  9. ......
  10. Looper.loop();
  11. ......
  12. thread.detach();
  13. ......
  14. }
  15. }
注意,执行到这里的时候,已经是在上一步创建的新进程里面了,即这里的进程是用来启动服务的,原来的主进程已经完成了它的命令,返回了。

前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。

Step 7.ActivityThread.attach

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalvoidattach(booleansystem){
  4. ......
  5. if(!system){
  6. ......
  7. IActivityManagermgr=ActivityManagerNative.getDefault();
  8. try{
  9. mgr.attachApplication(mAppThread);
  10. }catch(RemoteExceptionex){
  11. }
  12. }else{
  13. ......
  14. }
  15. ......
  16. }
  17. ......
  18. }
从Step 6中,这里传进来的参数system为false。成员变量mAppThread是一个ApplicationThread实例,我们在前面已经描述过这个实例的作用,它是用来辅助ActivityThread来执行一些操作的。

调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。

Step 8.ActivityManagerProxy.attachApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

view plain
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. publicvoidattachApplication(IApplicationThreadapp)throwsRemoteException
  5. {
  6. Parceldata=Parcel.obtain();
  7. Parcelreply=Parcel.obtain();
  8. data.writeInterfaceToken(IActivityManager.descriptor);
  9. data.writeStrongBinder(app.asBinder());
  10. mRemote.transact(ATTACH_APPLICATION_TRANSACTION,data,reply,0);
  11. reply.readException();
  12. data.recycle();
  13. reply.recycle();
  14. }
  15. ......
  16. }

这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。

Step 9. ActivityManagerService.attachApplication

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. publicfinalvoidattachApplication(IApplicationThreadthread)
  5. {
  6. synchronized(this){
  7. intcallingPid=Binder.getCallingPid();
  8. finallongorigId=Binder.clearCallingIdentity();
  9. attachApplicationLocked(thread,callingPid);
  10. Binder.restoreCallingIdentity(origId);
  11. }
  12. }
  13. ......
  14. }
这里通过调用attachApplicationLocked函数进一步处理。

Step 10.ActivityManagerService.attachApplicationLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalbooleanattachApplicationLocked(IApplicationThreadthread,
  5. intpid){
  6. //Findtheapplicationrecordthatisbeingattached...eithervia
  7. //thepidifwearerunninginmultipleprocesses,orjustpullthe
  8. //nextapprecordifweareemulatingprocesswithanonymousthreads.
  9. ProcessRecordapp;
  10. if(pid!=MY_PID&&pid>=0){
  11. synchronized(mPidsSelfLocked){
  12. app=mPidsSelfLocked.get(pid);
  13. }
  14. }elseif(mStartingProcesses.size()>0){
  15. app=mStartingProcesses.remove(0);
  16. app.setPid(pid);
  17. }else{
  18. app=null;
  19. }
  20. ......
  21. StringprocessName=app.processName;
  22. ......
  23. app.thread=thread;
  24. ......
  25. booleanbadApp=false;
  26. ......
  27. //Findanyservicesthatshouldberunninginthisprocess...
  28. if(!badApp&&mPendingServices.size()>0){
  29. ServiceRecordsr=null;
  30. try{
  31. for(inti=0;i<mPendingServices.size();i++){
  32. sr=mPendingServices.get(i);
  33. if(app.info.uid!=sr.appInfo.uid
  34. ||!processName.equals(sr.processName)){
  35. continue;
  36. }
  37. mPendingServices.remove(i);
  38. i--;
  39. realStartServiceLocked(sr,app);
  40. didSomething=true;
  41. }
  42. }catch(Exceptione){
  43. ......
  44. }
  45. }
  46. ......
  47. returntrue;
  48. }
  49. ......
  50. }
回忆一下在上面的Step 4中,以新进程的pid值作为key值保存了一个ProcessRecord在mPidsSelfLocked列表中,这里先把它取出来,存放在本地变量app中,并且将app.processName保存在本地变量processName中。

再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。

Step 11.ActivityManagerService.realStartServiceLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

view plain
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. privatefinalvoidrealStartServiceLocked(ServiceRecordr,
  5. ProcessRecordapp)throwsRemoteException{
  6. ......
  7. r.app=app;
  8. ......
  9. try{
  10. ......
  11. app.thread.scheduleCreateService(r,r.serviceInfo);
  12. ......
  13. }finally{
  14. ......
  15. }
  16. ......
  17. }
  18. ......
  19. }

这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。

Step 12. ApplicationThreadProxy.scheduleCreateService

这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

view plain
  1. classApplicationThreadProxyimplementsIApplicationThread{
  2. ......
  3. publicfinalvoidscheduleCreateService(IBindertoken,ServiceInfoinfo)
  4. throwsRemoteException{
  5. Parceldata=Parcel.obtain();
  6. data.writeInterfaceToken(IApplicationThread.descriptor);
  7. data.writeStrongBinder(token);
  8. info.writeToParcel(data,0);
  9. mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION,data,null,
  10. IBinder.FLAG_ONEWAY);
  11. data.recycle();
  12. }
  13. ......
  14. }

这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。

Step 13.ApplicationThread.scheduleCreateService

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalclassApplicationThreadextendsApplicationThreadNative{
  4. ......
  5. publicfinalvoidscheduleCreateService(IBindertoken,
  6. ServiceInfoinfo){
  7. CreateServiceDatas=newCreateServiceData();
  8. s.token=token;
  9. s.info=info;
  10. queueOrSendMessage(H.CREATE_SERVICE,s);
  11. }
  12. ......
  13. }
  14. ......
  15. }
这里调用ActivityThread的queueOrSendMessage将一个CreateServiceData数据放到消息队列中去,并且分开这个消息。注意,这里已经是在上面Step 4创建的新进程中执行了。

Step 14.ActivityThread.queueOrSendMessage

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalvoidqueueOrSendMessage(intwhat,Objectobj){
  4. queueOrSendMessage(what,obj,0,0);
  5. }
  6. privatefinalvoidqueueOrSendMessage(intwhat,Objectobj,intarg1,intarg2){
  7. synchronized(this){
  8. ......
  9. Messagemsg=Message.obtain();
  10. msg.what=what;
  11. msg.obj=obj;
  12. msg.arg1=arg1;
  13. msg.arg2=arg2;
  14. mH.sendMessage(msg);
  15. }
  16. }
  17. ......
  18. }

这里调用成员变量mH的sendMessage函数进行消息分发。这里的mH的类型为H,它继承于Handler类。

Step 15. H.sendMessage

这个函数继承于Handle类的sendMessage函数中,定义在frameworks/base/core/java/android/os/Handler.java文件中。这个函数我们就不看了,有兴趣的读者可以自己研究一下。消息分发以后,就进入到H.handleMessage函数进行处理了。

Step 16. H.handleMessage

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalclassHextendsHandler{
  4. ......
  5. publicvoidhandleMessage(Messagemsg){
  6. ......
  7. switch(msg.what){
  8. ......
  9. caseCREATE_SERVICE:
  10. handleCreateService((CreateServiceData)msg.obj);
  11. break;
  12. ......
  13. }
  14. ......
  15. }
  16. ......
  17. }
  18. ......
  19. }
这里要处理的消息是CREATE_SERVICE,它调用ActivityThread类的handleCreateService成员函数进一步处理。

Step 17.ActivityThread.handleCreateService

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalvoidhandleCreateService(CreateServiceDatadata){
  4. //Ifwearegettingreadytogcaftergoingtothebackground,well
  5. //wearebackactivesoskipit.
  6. unscheduleGcIdler();
  7. LoadedApkpackageInfo=getPackageInfoNoCheck(
  8. data.info.applicationInfo);
  9. Serviceservice=null;
  10. try{
  11. java.lang.ClassLoadercl=packageInfo.getClassLoader();
  12. service=(Service)cl.loadClass(data.info.name).newInstance();
  13. }catch(Exceptione){
  14. if(!mInstrumentation.onException(service,e)){
  15. thrownewRuntimeException(
  16. "Unabletoinstantiateservice"+data.info.name
  17. +":"+e.toString(),e);
  18. }
  19. }
  20. try{
  21. if(localLOGV)Slog.v(TAG,"Creatingservice"+data.info.name);
  22. ContextImplcontext=newContextImpl();
  23. context.init(packageInfo,null,this);
  24. Applicationapp=packageInfo.makeApplication(false,mInstrumentation);
  25. context.setOuterContext(service);
  26. service.attach(context,this,data.info.name,data.token,app,
  27. ActivityManagerNative.getDefault());
  28. service.onCreate();
  29. mServices.put(data.token,service);
  30. try{
  31. ActivityManagerNative.getDefault().serviceDoneExecuting(
  32. data.token,0,0,0);
  33. }catch(RemoteExceptione){
  34. //nothingtodo.
  35. }
  36. }catch(Exceptione){
  37. if(!mInstrumentation.onException(service,e)){
  38. thrownewRuntimeException(
  39. "Unabletocreateservice"+data.info.name
  40. +":"+e.toString(),e);
  41. }
  42. }
  43. }
  44. ......
  45. }
这里的data.info.name就是自定义的服务类shy.luo.ashmem.Server了。

Step 18. ClassLoader.loadClass

这一步实现在上面的ActivityThread.handleCreateService函数中:

view plain
  1. java.lang.ClassLoadercl=packageInfo.getClassLoader();
  2. service=(Service)cl.loadClass(data.info.name).newInstance();
Step 19. Obtain Service

这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。

Step 20. Service.onCreate

这一步继续实现在上面的ActivityThread.handleCreateService函数中:

view plain
  1. service.onCreate();
因为这里的service实际上是一个shy.luo.ashmem.Server类实例,因此,这里就是执行shy.luo.ashmem.Server类的onCreate函数了:
view plain
  1. publicclassServerextendsService{
  2. ......
  3. @Override
  4. publicvoidonCreate(){
  5. ......
  6. }
  7. ......
  8. }
至此,这个自定义的服务就启动起来了。

这样,Android系统在新进程中启动服务的过程就分析完成了,虽然很复杂,但是条理很清晰。它通过三次Binder进程间通信完成了服务的启动过程,分别是:

一. Step 1至Step 7,从主进程调用到ActivityManagerService进程中,完成新进程的创建;

二. Step 8至Step 11,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;

三. Step 12至Step 20,从ActivityManagerService进程又回到新进程中,最终将服务启动起来。

学习完Android系统在新进程中启动服务的过程后,希望读者对Android系统的Service有一个深刻的理解。在编写Android应用程序的时候,尽量把一些计算型的逻辑以Service在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics