- 浏览: 21367205 次
- 性别:
- 来自: 杭州
最新评论
-
ZY199266:
配置文件还需要额外的配置ma
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
ZY199266:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我又一个问题就是 如果像你的这种形式写。配置文件还需要额外的 ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
y1210251848:
你的那个错误应该是项目所使用的目标框架不支持吧
log4net配置(web中使用log4net,把web.config放在单独的文件中)
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类的一个成员函数:
- packageshy.luo.ashmem;
- ......
- publicclassClientextendsActivityimplementsOnClickListener{
- ......
- IMemoryServicememoryService=null;
- ......
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- ......
- IMemoryServicems=getMemoryService();
- if(ms==null){
- startService(newIntent("shy.luo.ashmem.server"));
- }else{
- Log.i(LOG_TAG,"MemoryServicehasstarted.");
- }
- ......
- Log.i(LOG_TAG,"ClientActivityCreated.");
- }
- ......
- }
这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:
- <manifestxmlns:android="http://schemas.android.com/apk/res/android"
- package="shy.luo.ashmem"
- android:sharedUserId="android.uid.system"
- android:versionCode="1"
- android:versionName="1.0">
- <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
- ......
- <service
- android:enabled="true"
- android:name=".Server"
- android:process=".Server">
- <intent-filter>
- <actionandroid:name="shy.luo.ashmem.server"/>
- <categoryandroid:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </service>
- </application>
- </manifest>
- startService(newIntent("shy.luo.ashmem.server"));
- packageshy.luo.ashmem;
- ......
- publicclassServerextendsService{
- ......
- @Override
- publicIBinderonBind(Intentintent){
- returnnull;
- }
- @Override
- publicvoidonCreate(){
- ......
- }
- ......
- }
先来看看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启动相关的代码:
- classServerThreadextendsThread{
- ......
- @Override
- publicvoidrun(){
- ......
- //Criticalservices...
- try{
- ......
- context=ActivityManagerService.main(factoryTest);
- ......
- ActivityManagerService.setSystemProcess();
- ......
- }catch(RuntimeExceptione){
- Slog.e("System","Failurestartingcoreservice",e);
- }
- ......
- }
- ......
- }
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- staticActivityManagerServicemSelf;
- ......
- publicstaticvoidsetSystemProcess(){
- try{
- ActivityManagerServicem=mSelf;
- ServiceManager.addService("activity",m);
- ......
- }catch(PackageManager.NameNotFoundExceptione){
- ......
- }
- }
- ......
- publicstaticfinalContextmain(intfactoryTest){
- ......
- ActivityManagerServicem=thr.mService;
- mSelf=m;
- ......
- }
- }
回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
- StringresolvedType)throwsRemoteException
- {
- Parceldata=Parcel.obtain();
- Parcelreply=Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(caller!=null?caller.asBinder():null);
- service.writeToParcel(data,0);
- data.writeString(resolvedType);
- mRemote.transact(START_SERVICE_TRANSACTION,data,reply,0);
- reply.readException();
- ComponentNameres=ComponentName.readFromParcel(reply);
- data.recycle();
- reply.recycle();
- returnres;
- }
- ......
- }
参数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文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
- StringresolvedType){
- //Refusepossibleleakedfiledescriptors
- if(service!=null&&service.hasFileDescriptors()==true){
- thrownewIllegalArgumentException("FiledescriptorspassedinIntent");
- }
- synchronized(this){
- finalintcallingPid=Binder.getCallingPid();
- finalintcallingUid=Binder.getCallingUid();
- finallongorigId=Binder.clearCallingIdentity();
- ComponentNameres=startServiceLocked(caller,service,
- resolvedType,callingPid,callingUid);
- Binder.restoreCallingIdentity(origId);
- returnres;
- }
- }
- ......
- }
Step 2.ActivityManagerService.startServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- ComponentNamestartServiceLocked(IApplicationThreadcaller,
- Intentservice,StringresolvedType,
- intcallingPid,intcallingUid){
- synchronized(this){
- ......
- ServiceLookupResultres=
- retrieveServiceLocked(service,resolvedType,
- callingPid,callingUid);
- ......
- ServiceRecordr=res.record;
- ......
- if(!bringUpServiceLocked(r,service.getFlags(),false)){
- returnnewComponentName("!","Serviceprocessisbad");
- }
- returnr.name;
- }
- }
- ......
- }
Step 3. ActivityManagerService.bringUpServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalbooleanbringUpServiceLocked(ServiceRecordr,
- intintentFlags,booleanwhileRestarting){
- ......
- finalStringappName=r.processName;
- ......
- //Notrunning--getitstarted,andenqueuethisservicerecord
- //tobeexecutedwhentheappcomesup.
- if(startProcessLocked(appName,r.appInfo,true,intentFlags,
- "service",r.name,false)==null){
- ......
- returnfalse;
- }
- if(!mPendingServices.contains(r)){
- mPendingServices.add(r);
- }
- returntrue;
- }
- ......
- }
接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。
Step 4.ActivityManagerService.startProcessLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidstartProcessLocked(ProcessRecordapp,
- StringhostingType,StringhostingNameStr){
- ......
- try{
- ......
- intpid=Process.start("android.app.ActivityThread",
- mSimpleProcessManagement?app.processName:null,uid,uid,
- gids,debugFlags,null);
- ......
- if(pid==0||pid==MY_PID){
- ......
- }elseif(pid>0){
- app.pid=pid;
- app.removed=false;
- synchronized(mPidsSelfLocked){
- this.mPidsSelfLocked.put(pid,app);
- ......
- }
- }else{
- ......
- }
- }catch(RuntimeExceptione){
- ......
- }
- }
- ......
- }
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文件中:
- publicfinalclassActivityThread{
- ......
- publicstaticfinalvoidmain(String[]args){
- ......
- Looper.prepareMainLooper();
- ......
- ActivityThreadthread=newActivityThread();
- thread.attach(false);
- ......
- Looper.loop();
- ......
- thread.detach();
- ......
- }
- }
前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。
Step 7.ActivityThread.attach
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidattach(booleansystem){
- ......
- if(!system){
- ......
- IActivityManagermgr=ActivityManagerNative.getDefault();
- try{
- mgr.attachApplication(mAppThread);
- }catch(RemoteExceptionex){
- }
- }else{
- ......
- }
- ......
- }
- ......
- }
调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。
Step 8.ActivityManagerProxy.attachApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicvoidattachApplication(IApplicationThreadapp)throwsRemoteException
- {
- Parceldata=Parcel.obtain();
- Parcelreply=Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(app.asBinder());
- mRemote.transact(ATTACH_APPLICATION_TRANSACTION,data,reply,0);
- reply.readException();
- data.recycle();
- reply.recycle();
- }
- ......
- }
这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。
Step 9. ActivityManagerService.attachApplication
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicfinalvoidattachApplication(IApplicationThreadthread)
- {
- synchronized(this){
- intcallingPid=Binder.getCallingPid();
- finallongorigId=Binder.clearCallingIdentity();
- attachApplicationLocked(thread,callingPid);
- Binder.restoreCallingIdentity(origId);
- }
- }
- ......
- }
Step 10.ActivityManagerService.attachApplicationLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalbooleanattachApplicationLocked(IApplicationThreadthread,
- intpid){
- //Findtheapplicationrecordthatisbeingattached...eithervia
- //thepidifwearerunninginmultipleprocesses,orjustpullthe
- //nextapprecordifweareemulatingprocesswithanonymousthreads.
- ProcessRecordapp;
- if(pid!=MY_PID&&pid>=0){
- synchronized(mPidsSelfLocked){
- app=mPidsSelfLocked.get(pid);
- }
- }elseif(mStartingProcesses.size()>0){
- app=mStartingProcesses.remove(0);
- app.setPid(pid);
- }else{
- app=null;
- }
- ......
- StringprocessName=app.processName;
- ......
- app.thread=thread;
- ......
- booleanbadApp=false;
- ......
- //Findanyservicesthatshouldberunninginthisprocess...
- if(!badApp&&mPendingServices.size()>0){
- ServiceRecordsr=null;
- try{
- for(inti=0;i<mPendingServices.size();i++){
- sr=mPendingServices.get(i);
- if(app.info.uid!=sr.appInfo.uid
- ||!processName.equals(sr.processName)){
- continue;
- }
- mPendingServices.remove(i);
- i--;
- realStartServiceLocked(sr,app);
- didSomething=true;
- }
- }catch(Exceptione){
- ......
- }
- }
- ......
- returntrue;
- }
- ......
- }
再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。
Step 11.ActivityManagerService.realStartServiceLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- privatefinalvoidrealStartServiceLocked(ServiceRecordr,
- ProcessRecordapp)throwsRemoteException{
- ......
- r.app=app;
- ......
- try{
- ......
- app.thread.scheduleCreateService(r,r.serviceInfo);
- ......
- }finally{
- ......
- }
- ......
- }
- ......
- }
这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。
Step 12. ApplicationThreadProxy.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
- classApplicationThreadProxyimplementsIApplicationThread{
- ......
- publicfinalvoidscheduleCreateService(IBindertoken,ServiceInfoinfo)
- throwsRemoteException{
- Parceldata=Parcel.obtain();
- data.writeInterfaceToken(IApplicationThread.descriptor);
- data.writeStrongBinder(token);
- info.writeToParcel(data,0);
- mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION,data,null,
- IBinder.FLAG_ONEWAY);
- data.recycle();
- }
- ......
- }
这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。
Step 13.ApplicationThread.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalclassApplicationThreadextendsApplicationThreadNative{
- ......
- publicfinalvoidscheduleCreateService(IBindertoken,
- ServiceInfoinfo){
- CreateServiceDatas=newCreateServiceData();
- s.token=token;
- s.info=info;
- queueOrSendMessage(H.CREATE_SERVICE,s);
- }
- ......
- }
- ......
- }
Step 14.ActivityThread.queueOrSendMessage
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidqueueOrSendMessage(intwhat,Objectobj){
- queueOrSendMessage(what,obj,0,0);
- }
- privatefinalvoidqueueOrSendMessage(intwhat,Objectobj,intarg1,intarg2){
- synchronized(this){
- ......
- Messagemsg=Message.obtain();
- msg.what=what;
- msg.obj=obj;
- msg.arg1=arg1;
- msg.arg2=arg2;
- mH.sendMessage(msg);
- }
- }
- ......
- }
这里调用成员变量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文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalclassHextendsHandler{
- ......
- publicvoidhandleMessage(Messagemsg){
- ......
- switch(msg.what){
- ......
- caseCREATE_SERVICE:
- handleCreateService((CreateServiceData)msg.obj);
- break;
- ......
- }
- ......
- }
- ......
- }
- ......
- }
Step 17.ActivityThread.handleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidhandleCreateService(CreateServiceDatadata){
- //Ifwearegettingreadytogcaftergoingtothebackground,well
- //wearebackactivesoskipit.
- unscheduleGcIdler();
- LoadedApkpackageInfo=getPackageInfoNoCheck(
- data.info.applicationInfo);
- Serviceservice=null;
- try{
- java.lang.ClassLoadercl=packageInfo.getClassLoader();
- service=(Service)cl.loadClass(data.info.name).newInstance();
- }catch(Exceptione){
- if(!mInstrumentation.onException(service,e)){
- thrownewRuntimeException(
- "Unabletoinstantiateservice"+data.info.name
- +":"+e.toString(),e);
- }
- }
- try{
- if(localLOGV)Slog.v(TAG,"Creatingservice"+data.info.name);
- ContextImplcontext=newContextImpl();
- context.init(packageInfo,null,this);
- Applicationapp=packageInfo.makeApplication(false,mInstrumentation);
- context.setOuterContext(service);
- service.attach(context,this,data.info.name,data.token,app,
- ActivityManagerNative.getDefault());
- service.onCreate();
- mServices.put(data.token,service);
- try{
- ActivityManagerNative.getDefault().serviceDoneExecuting(
- data.token,0,0,0);
- }catch(RemoteExceptione){
- //nothingtodo.
- }
- }catch(Exceptione){
- if(!mInstrumentation.onException(service,e)){
- thrownewRuntimeException(
- "Unabletocreateservice"+data.info.name
- +":"+e.toString(),e);
- }
- }
- }
- ......
- }
Step 18. ClassLoader.loadClass
这一步实现在上面的ActivityThread.handleCreateService函数中:
- java.lang.ClassLoadercl=packageInfo.getClassLoader();
- service=(Service)cl.loadClass(data.info.name).newInstance();
这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。
Step 20. Service.onCreate
这一步继续实现在上面的ActivityThread.handleCreateService函数中:
- service.onCreate();
- publicclassServerextendsService{
- ......
- @Override
- publicvoidonCreate(){
- ......
- }
- ......
- }
这样,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类的一个成员函数:
- packageshy.luo.ashmem;
- ......
- publicclassClientextendsActivityimplementsOnClickListener{
- ......
- IMemoryServicememoryService=null;
- ......
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- ......
- IMemoryServicems=getMemoryService();
- if(ms==null){
- startService(newIntent("shy.luo.ashmem.server"));
- }else{
- Log.i(LOG_TAG,"MemoryServicehasstarted.");
- }
- ......
- Log.i(LOG_TAG,"ClientActivityCreated.");
- }
- ......
- }
这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:
- <manifestxmlns:android="http://schemas.android.com/apk/res/android"
- package="shy.luo.ashmem"
- android:sharedUserId="android.uid.system"
- android:versionCode="1"
- android:versionName="1.0">
- <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
- ......
- <service
- android:enabled="true"
- android:name=".Server"
- android:process=".Server">
- <intent-filter>
- <actionandroid:name="shy.luo.ashmem.server"/>
- <categoryandroid:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </service>
- </application>
- </manifest>
- startService(newIntent("shy.luo.ashmem.server"));
- packageshy.luo.ashmem;
- ......
- publicclassServerextendsService{
- ......
- @Override
- publicIBinderonBind(Intentintent){
- returnnull;
- }
- @Override
- publicvoidonCreate(){
- ......
- }
- ......
- }
先来看看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启动相关的代码:
- classServerThreadextendsThread{
- ......
- @Override
- publicvoidrun(){
- ......
- //Criticalservices...
- try{
- ......
- context=ActivityManagerService.main(factoryTest);
- ......
- ActivityManagerService.setSystemProcess();
- ......
- }catch(RuntimeExceptione){
- Slog.e("System","Failurestartingcoreservice",e);
- }
- ......
- }
- ......
- }
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- staticActivityManagerServicemSelf;
- ......
- publicstaticvoidsetSystemProcess(){
- try{
- ActivityManagerServicem=mSelf;
- ServiceManager.addService("activity",m);
- ......
- }catch(PackageManager.NameNotFoundExceptione){
- ......
- }
- }
- ......
- publicstaticfinalContextmain(intfactoryTest){
- ......
- ActivityManagerServicem=thr.mService;
- mSelf=m;
- ......
- }
- }
回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
- StringresolvedType)throwsRemoteException
- {
- Parceldata=Parcel.obtain();
- Parcelreply=Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(caller!=null?caller.asBinder():null);
- service.writeToParcel(data,0);
- data.writeString(resolvedType);
- mRemote.transact(START_SERVICE_TRANSACTION,data,reply,0);
- reply.readException();
- ComponentNameres=ComponentName.readFromParcel(reply);
- data.recycle();
- reply.recycle();
- returnres;
- }
- ......
- }
参数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文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicComponentNamestartService(IApplicationThreadcaller,Intentservice,
- StringresolvedType){
- //Refusepossibleleakedfiledescriptors
- if(service!=null&&service.hasFileDescriptors()==true){
- thrownewIllegalArgumentException("FiledescriptorspassedinIntent");
- }
- synchronized(this){
- finalintcallingPid=Binder.getCallingPid();
- finalintcallingUid=Binder.getCallingUid();
- finallongorigId=Binder.clearCallingIdentity();
- ComponentNameres=startServiceLocked(caller,service,
- resolvedType,callingPid,callingUid);
- Binder.restoreCallingIdentity(origId);
- returnres;
- }
- }
- ......
- }
Step 2.ActivityManagerService.startServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- ComponentNamestartServiceLocked(IApplicationThreadcaller,
- Intentservice,StringresolvedType,
- intcallingPid,intcallingUid){
- synchronized(this){
- ......
- ServiceLookupResultres=
- retrieveServiceLocked(service,resolvedType,
- callingPid,callingUid);
- ......
- ServiceRecordr=res.record;
- ......
- if(!bringUpServiceLocked(r,service.getFlags(),false)){
- returnnewComponentName("!","Serviceprocessisbad");
- }
- returnr.name;
- }
- }
- ......
- }
Step 3. ActivityManagerService.bringUpServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalbooleanbringUpServiceLocked(ServiceRecordr,
- intintentFlags,booleanwhileRestarting){
- ......
- finalStringappName=r.processName;
- ......
- //Notrunning--getitstarted,andenqueuethisservicerecord
- //tobeexecutedwhentheappcomesup.
- if(startProcessLocked(appName,r.appInfo,true,intentFlags,
- "service",r.name,false)==null){
- ......
- returnfalse;
- }
- if(!mPendingServices.contains(r)){
- mPendingServices.add(r);
- }
- returntrue;
- }
- ......
- }
接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。
Step 4.ActivityManagerService.startProcessLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidstartProcessLocked(ProcessRecordapp,
- StringhostingType,StringhostingNameStr){
- ......
- try{
- ......
- intpid=Process.start("android.app.ActivityThread",
- mSimpleProcessManagement?app.processName:null,uid,uid,
- gids,debugFlags,null);
- ......
- if(pid==0||pid==MY_PID){
- ......
- }elseif(pid>0){
- app.pid=pid;
- app.removed=false;
- synchronized(mPidsSelfLocked){
- this.mPidsSelfLocked.put(pid,app);
- ......
- }
- }else{
- ......
- }
- }catch(RuntimeExceptione){
- ......
- }
- }
- ......
- }
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文件中:
- publicfinalclassActivityThread{
- ......
- publicstaticfinalvoidmain(String[]args){
- ......
- Looper.prepareMainLooper();
- ......
- ActivityThreadthread=newActivityThread();
- thread.attach(false);
- ......
- Looper.loop();
- ......
- thread.detach();
- ......
- }
- }
前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。
Step 7.ActivityThread.attach
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidattach(booleansystem){
- ......
- if(!system){
- ......
- IActivityManagermgr=ActivityManagerNative.getDefault();
- try{
- mgr.attachApplication(mAppThread);
- }catch(RemoteExceptionex){
- }
- }else{
- ......
- }
- ......
- }
- ......
- }
调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。
Step 8.ActivityManagerProxy.attachApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicvoidattachApplication(IApplicationThreadapp)throwsRemoteException
- {
- Parceldata=Parcel.obtain();
- Parcelreply=Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(app.asBinder());
- mRemote.transact(ATTACH_APPLICATION_TRANSACTION,data,reply,0);
- reply.readException();
- data.recycle();
- reply.recycle();
- }
- ......
- }
这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。
Step 9. ActivityManagerService.attachApplication
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicfinalvoidattachApplication(IApplicationThreadthread)
- {
- synchronized(this){
- intcallingPid=Binder.getCallingPid();
- finallongorigId=Binder.clearCallingIdentity();
- attachApplicationLocked(thread,callingPid);
- Binder.restoreCallingIdentity(origId);
- }
- }
- ......
- }
Step 10.ActivityManagerService.attachApplicationLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalbooleanattachApplicationLocked(IApplicationThreadthread,
- intpid){
- //Findtheapplicationrecordthatisbeingattached...eithervia
- //thepidifwearerunninginmultipleprocesses,orjustpullthe
- //nextapprecordifweareemulatingprocesswithanonymousthreads.
- ProcessRecordapp;
- if(pid!=MY_PID&&pid>=0){
- synchronized(mPidsSelfLocked){
- app=mPidsSelfLocked.get(pid);
- }
- }elseif(mStartingProcesses.size()>0){
- app=mStartingProcesses.remove(0);
- app.setPid(pid);
- }else{
- app=null;
- }
- ......
- StringprocessName=app.processName;
- ......
- app.thread=thread;
- ......
- booleanbadApp=false;
- ......
- //Findanyservicesthatshouldberunninginthisprocess...
- if(!badApp&&mPendingServices.size()>0){
- ServiceRecordsr=null;
- try{
- for(inti=0;i<mPendingServices.size();i++){
- sr=mPendingServices.get(i);
- if(app.info.uid!=sr.appInfo.uid
- ||!processName.equals(sr.processName)){
- continue;
- }
- mPendingServices.remove(i);
- i--;
- realStartServiceLocked(sr,app);
- didSomething=true;
- }
- }catch(Exceptione){
- ......
- }
- }
- ......
- returntrue;
- }
- ......
- }
再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。
Step 11.ActivityManagerService.realStartServiceLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- privatefinalvoidrealStartServiceLocked(ServiceRecordr,
- ProcessRecordapp)throwsRemoteException{
- ......
- r.app=app;
- ......
- try{
- ......
- app.thread.scheduleCreateService(r,r.serviceInfo);
- ......
- }finally{
- ......
- }
- ......
- }
- ......
- }
这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。
Step 12. ApplicationThreadProxy.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
- classApplicationThreadProxyimplementsIApplicationThread{
- ......
- publicfinalvoidscheduleCreateService(IBindertoken,ServiceInfoinfo)
- throwsRemoteException{
- Parceldata=Parcel.obtain();
- data.writeInterfaceToken(IApplicationThread.descriptor);
- data.writeStrongBinder(token);
- info.writeToParcel(data,0);
- mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION,data,null,
- IBinder.FLAG_ONEWAY);
- data.recycle();
- }
- ......
- }
这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。
Step 13.ApplicationThread.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalclassApplicationThreadextendsApplicationThreadNative{
- ......
- publicfinalvoidscheduleCreateService(IBindertoken,
- ServiceInfoinfo){
- CreateServiceDatas=newCreateServiceData();
- s.token=token;
- s.info=info;
- queueOrSendMessage(H.CREATE_SERVICE,s);
- }
- ......
- }
- ......
- }
Step 14.ActivityThread.queueOrSendMessage
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidqueueOrSendMessage(intwhat,Objectobj){
- queueOrSendMessage(what,obj,0,0);
- }
- privatefinalvoidqueueOrSendMessage(intwhat,Objectobj,intarg1,intarg2){
- synchronized(this){
- ......
- Messagemsg=Message.obtain();
- msg.what=what;
- msg.obj=obj;
- msg.arg1=arg1;
- msg.arg2=arg2;
- mH.sendMessage(msg);
- }
- }
- ......
- }
这里调用成员变量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文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalclassHextendsHandler{
- ......
- publicvoidhandleMessage(Messagemsg){
- ......
- switch(msg.what){
- ......
- caseCREATE_SERVICE:
- handleCreateService((CreateServiceData)msg.obj);
- break;
- ......
- }
- ......
- }
- ......
- }
- ......
- }
Step 17.ActivityThread.handleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidhandleCreateService(CreateServiceDatadata){
- //Ifwearegettingreadytogcaftergoingtothebackground,well
- //wearebackactivesoskipit.
- unscheduleGcIdler();
- LoadedApkpackageInfo=getPackageInfoNoCheck(
- data.info.applicationInfo);
- Serviceservice=null;
- try{
- java.lang.ClassLoadercl=packageInfo.getClassLoader();
- service=(Service)cl.loadClass(data.info.name).newInstance();
- }catch(Exceptione){
- if(!mInstrumentation.onException(service,e)){
- thrownewRuntimeException(
- "Unabletoinstantiateservice"+data.info.name
- +":"+e.toString(),e);
- }
- }
- try{
- if(localLOGV)Slog.v(TAG,"Creatingservice"+data.info.name);
- ContextImplcontext=newContextImpl();
- context.init(packageInfo,null,this);
- Applicationapp=packageInfo.makeApplication(false,mInstrumentation);
- context.setOuterContext(service);
- service.attach(context,this,data.info.name,data.token,app,
- ActivityManagerNative.getDefault());
- service.onCreate();
- mServices.put(data.token,service);
- try{
- ActivityManagerNative.getDefault().serviceDoneExecuting(
- data.token,0,0,0);
- }catch(RemoteExceptione){
- //nothingtodo.
- }
- }catch(Exceptione){
- if(!mInstrumentation.onException(service,e)){
- thrownewRuntimeException(
- "Unabletocreateservice"+data.info.name
- +":"+e.toString(),e);
- }
- }
- }
- ......
- }
Step 18. ClassLoader.loadClass
这一步实现在上面的ActivityThread.handleCreateService函数中:
- java.lang.ClassLoadercl=packageInfo.getClassLoader();
- service=(Service)cl.loadClass(data.info.name).newInstance();
这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。
Step 20. Service.onCreate
这一步继续实现在上面的ActivityThread.handleCreateService函数中:
- service.onCreate();
- publicclassServerextendsService{
- ......
- @Override
- publicvoidonCreate(){
- ......
- }
- ......
- }
这样,Android系统在新进程中启动服务的过程就分析完成了,虽然很复杂,但是条理很清晰。它通过三次Binder进程间通信完成了服务的启动过程,分别是:
一. Step 1至Step 7,从主进程调用到ActivityManagerService进程中,完成新进程的创建;
二. Step 8至Step 11,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;
三. Step 12至Step 20,从ActivityManagerService进程又回到新进程中,最终将服务启动起来。
学习完Android系统在新进程中启动服务的过程后,希望读者对Android系统的Service有一个深刻的理解。在编写Android应用程序的时候,尽量把一些计算型的逻辑以Service在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。
相关推荐
Android系统在新进程中启动自定义服务过程(startService)的原理分析
(Android系统进程Zygote启动过程的源代码分析UML,Android系统默认Home应用程序(Launcher)的启动过程源代码分析uml,Android系统在新进程中启动自定义服务过程(startService)的原理分析UML,Android应用程序...
android startService小demo,适合初学者。
Android防止service多次执行startCommand 博客地址:http://blog.csdn.net/yuzhiqiang_1993/article/details/78211385
用AndroidStudio编写,里面的Activity有三个按钮,用startService函数分别启动三个服务,一 个是通过继承Service类实现的服务,一个是通过继承Service类在里面定义一个线程来处理服务,还有一个是通过继承...
android startService 资源,网上下的
Android Service的startService()的启动方式,并结合案例
于Android启动过程复杂,涉及C、C++及java部分内容,本文以流程分析为主线旨在让大家在分析Android系统时有个清晰的思路。鉴于本人水平有限,如有阐述不正之处,还请不吝指正,感激不尽! 系统启动大致可分为一下几...
StartService方式启动Service,并实现简单逻辑操作
start service 启动不了解决方案
Android Service之start实现
使用.Net的进程的Start方法在impersonated credentials下从服务中启动一个进程,可以解决权限问题。
实例详解Android中startService()和bindService()的区别。 说明详见http://blog.csdn.net/a343902152/article/details/50857316
Android中有两种主要方式...当我们通过调用了Context的startService方法后,我们便启动了Service,通过startService方法启动的Service会一直无限期地运行下去,只有在外部调用Context的stopService或Service内部调用
NULL 博文链接:https://rainbow702.iteye.com/blog/1142685
关于startService的基本使用概述及其生命周期可参见《Android中startService基本使用方法概述》。 本文通过播放背景音乐的简单示例,演示startService的基本使用流程,具体内容如下 系统界面如下: 界面上面就两...
在AndrodStudio中点击模拟器的启动按钮后,模拟器界面弹出后,又立刻闪退。下面通过本文给大家分享ubuntu上在androidstudio中启动emulator闪退的解决方法,一起看看吧
使用startservice方法启动服务,并检测服务的生命周期
1、startService开启服务以后,与activity就没有关联,不受影响,独立运行,需要stopService关闭,否则Activity移除栈后将一直运行(kill杀不死). 2、bindService开启服务以后,与activity存在关联,退出activity时...