Android Service启动绑定流程是什么

免费教程   2024年05月08日 7:31  

这篇文章主要介绍了AndroidService启动绑定流程是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇AndroidService启动绑定流程是什么文章都会有所收获,下面我们一起来看看吧。

一、 的启动流程1、ContextImpl.startService

启动一个Service,通常在Activity调用startService来启动。

@OverridepublicComponentNamestartService(Intentservice){returnstartServiceCommon(service,false,mUser);}2、ContextImpl.startServiceCommon

startServiceCommon检查intent内容是否合法,然后做一些离开当前进程的准备操作。调用 ActivityManager.getService()获得AMS的本地引用,并调用其startService函数。

也就是说通过Binder机制跨进程通信调用了AMS的startService函数。

privateComponentNamestartServiceCommon(Intentservice,booleanrequireForeground,UserHandleuser){try{//检查intent的compant和package是否合法validateServiceIntent(service);...ComponentNamecn=ActivityManager.getService().startService(mMainThread.getApplicationThread(),service,service.resolveTypeIfNeeded(getContentResolver()),requireForeground,getOpPackageName(),getAttributionTag(),user.getIdentifier());...returncn;}catch(RemoteExceptione){throwe.rethrowFromSystemServer();}}

通过 ActivityManager.getService()的实现。

@UnsupportedAppUsagepublicstaticIActivityManagergetService(){returnIActivityManagerSingleton.get();}@UnsupportedAppUsageprivatestaticfinalSingleton<IActivityManager>IActivityManagerSingleton=newSingleton<IActivityManager>(){@OverrideprotectedIActivityManagercreate(){finalIBinderb=ServiceManager.getService(Context.ACTIVITY_SERVICE);finalIActivityManageram=IActivityManager.Stub.asInterface(b);returnam;}};3、AMS.startService

AMS.startService函数获取调用Pid和Uid,然后调用ActiveService的startServiceLocked函数。

@OverridepublicComponentNamestartService(IApplicationThreadcaller,Intentservice,StringresolvedType,booleanrequireForeground,StringcallingPackage,StringcallingFeatureId,intuserId)throwsTransactionTooLargeException{...synchronized(this){finalintcallingPid=Binder.getCallingPid();finalintcallingUid=Binder.getCallingUid();finallongorigId=Binder.clearCallingIdentity();ComponentNameres;try{res=mServices.startServiceLocked(caller,service,resolvedType,callingPid,callingUid,requireForeground,callingPackage,callingFeatureId,userId);}finally{Binder.restoreCallingIdentity(origId);}returnres;}}4、ActiveService.startServiceLock

ActiveService.startServiceLock函数,对一些合法性的检查,例如前台Service的权限、限制性后台Service进行延迟运行(standby)。并将要启动的信息封装成ServiceRecord。然后调用了startServiceInnerLocked函数。

ComponentNamestartServiceLocked(IApplicationThreadcaller,Intentservice,StringresolvedType,intcallingPid,intcallingUid,booleanfgRequired,StringcallingPackage,@NullableStringcallingFeatureId,finalintuserId)throwsTransactionTooLargeException{returnstartServiceLocked(caller,service,resolvedType,callingPid,callingUid,fgRequired,callingPackage,callingFeatureId,userId,false);}ComponentNamestartServiceLocked(IApplicationThreadcaller,Intentservice,StringresolvedType,intcallingPid,intcallingUid,booleanfgRequired,StringcallingPackage,@NullableStringcallingFeatureId,finalintuserId,booleanallowBackgroundActivityStarts)throwsTransactionTooLargeException{finalbooleancallerFg;if(caller!=null){//获取调用Service的应用程序进程描述finalProcessRecordcallerApp=mAm.getRecordForAppLocked(caller);if(callerApp==null){...}callerFg=callerApp.setSchedGroup!=ProcessList.SCHED_GROUP_BACKGROUND;}else{callerFg=true;}//检索ServiceRecord,包括同应用和其他应用ServiceLookupResultres=retrieveServiceLocked(service,null,resolvedType,callingPackage,callingPid,callingUid,userId,true,callerFg,false,false);...//要启动的ServiceRecordServiceRecordr=res.record;...r.lastActivity=SystemClock.uptimeMillis();r.startRequested=true;r.delayedStop=false;r.fgRequired=fgRequired;r.pendingStarts.add(newServiceRecord.StartItem(r,false,r.makeNextStartId(),service,neededGrants,callingUid));ComponentNamecmp=startServiceInnerLocked(smap,service,r,callerFg,addToStarting);...returncmp;}5、ActiveServices.startServiceInnerLocker

调用了bringUpServiceLocked函数,会将ServiceRecord添加到ServiceMap类型的smap集合,进行缓存。

ComponentNamestartServiceInnerLocked(ServiceMapsmap,Intentservice,ServiceRecordr,booleancallerFg,booleanaddToStarting)throwsTransactionTooLargeException{r.callStart=false;...Stringerror=bringUpServiceLocked(r,service.getFlags(),callerFg,false,false);...returnr.name;}6、 ActiveService.bringUpServiceLocked

分析一:首次启动Service时,在执行bringUpServiceLocked函数,ServiceRecord是属于新创建的,而非从AMS的缓存mServices中检索而来,所以此时的ServiceRecord的ProcessRecord类型app和IApplicationThread类型thread都是null。只有启动过后的ServiceRecord才有值,才会执行sendServiceArgsLocked函数,重复调用Service的生命周期onStartCommand,而不调用onCreate函数。

privateStringbringUpServiceLocked(ServiceRecordr,intintentFlags,booleanexecInFg,booleanwhileRestarting,booleanpermissionsReviewRequired)throwsTransactionTooLargeException{//分析一:未启动过的ServiceRecord两者都是null,重复启动会执行该函数,//会重复调用service的onStartCommand函数。if(r.app!=null&amp;&amp;r.app.thread!=null){sendServiceArgsLocked(r,execInFg,false);returnnull;}...finalbooleanisolated=(r.serviceInfo.flags&amp;ServiceInfo.FLAG_ISOLATED_PROCESS)!=0;finalStringprocName=r.processName;HostingRecordhostingRecord=newHostingRecord("service",r.instanceName);ProcessRecordapp;if(!isolated){////通过AMS获取service所在进程的ProcessRecord。ProcessList=&gt;MyProcessMap=》会缓存已创建过进程的ProcessRecordapp=mAm.getProcessRecordLocked(procName,r.appInfo.uid,false);if(app!=null&amp;&amp;app.thread!=null){try{app.addPackage(r.appInfo.packageName,r.appInfo.longVersionCode,mAm.mProcessStats);//启动服务realStartServiceLocked(r,app,execInFg);returnnull;}catch(TransactionTooLargeExceptione){throwe;}catch(RemoteExceptione){Slog.w(TAG,"Exceptionwhenstartingservice"+r.shortInstanceName,e);}}}//如果service所在的进程未启动,通过AMS启动该进程,可以参考应用进程的启动流程if(app==null&amp;&amp;!permissionsReviewRequired){if((app=mAm.startProcessLocked(procName,r.appInfo,true,intentFlags,hostingRecord,ZYGOTE_POLICY_FLAG_EMPTY,false,isolated,false))==null){;bringDownServiceLocked(r);returnmsg;}if(isolated){r.isolatedProc=app;}}//等待进程启动完毕重启启动if(!mPendingServices.contains(r)){mPendingServices.add(r);}...returnnull;}7、ActiveService.realStartServiceLockedprivatefinalvoidrealStartServiceLocked(ServiceRecordr,ProcessRecordapp,booleanexecInFg)throwsRemoteException{//将ProcessRecord设置给ServiceRecordr.setProcess(app);//登记当ServiceRecord到ProcessRecordd的数组mServices,表示Service已经启动(实际未启动)finalbooleannewService=app.startService(r);booleancreated=false;try{...app.thread.scheduleCreateService(r,r.serviceInfo,mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),app.getReportedProcState());...}catch(DeadObjectExceptione){Slog.w(TAG,"Applicationdeadwhencreatingservice"+r);mAm.appDiedLocked(app,"Diedwhencreatingservice");throwe;}//会调用Service的onStartCommand函数sendServiceArgsLocked(r,execInFg,true);...}

通过ProcessRecord对象的IApplicationThread引用,通过Binder机制调用了应用程序的ApplicationThread的scheduleCreateService函数。

8、ApplicationThread.scheduleCreateService

将ServiceInfo等相关信息封装到CreateServiceData中,并发送给ActivityThread的H类型的mH对象。

publicfinalvoidscheduleCreateService(IBindertoken,ServiceInfoinfo,CompatibilityInfocompatInfo,intprocessState){updateProcessState(processState,false);CreateServiceDatas=newCreateServiceData();s.token=token;s.info=info;s.compatInfo=compatInfo;sendMessage(H.CREATE_SERVICE,s);}9、H.handleMesssage

调用了ActivityThread的handleCreateService函数。

caseCREATE_SERVICE:handleCreateService((CreateServiceData)msg.obj);break;10、ActivityThread.handleCreateServiceprivatevoidhandleCreateService(CreateServiceDatadata){...//获取当前应用的描述信息LoadedApkLoadedApkpackageInfo=getPackageInfoNoCheck(data.info.applicationInfo,data.compatInfo);Serviceservice=null;try{//创建Service的上下问文ContextImplcontext=ContextImpl.createAppContext(this,packageInfo);//获取当前应用Applcation对象Applicationapp=packageInfo.makeApplication(false,mInstrumentation);//通过反射创建Service对象java.lang.ClassLoadercl=packageInfo.getClassLoader();service=packageInfo.getAppFactory().instantiateService(cl,data.info.name,data.intent);//初始化资源context.getResources().addLoaders(app.getResources().getLoaders().toArray(newResourcesLoader[0]));//context与service相互绑定context.setOuterContext(service);service.attach(context,this,data.info.name,data.token,app,ActivityManager.getService());//调用Service的生命周期onCreate函数,意味Service创建完毕service.onCreate();//缓存ServicemServices.put(data.token,service);try{ActivityManager.getService().serviceDoneExecuting(data.token,SERVICE_DONE_EXECUTING_ANON,0,0);}catch(RemoteExceptione){throwe.rethrowFromSystemServer();}}catch(Exceptione){if(!mInstrumentation.onException(service,e)){thrownewRuntimeException("Unabletocreateservice"+data.info.name+":"+e.toString(),e);}}}

通过ContextImpl.createAppContext创建Service的上下文context,通过packageInfo.getAppFactory().instantiateService反射获得当前Service对象service,将context与service相互绑定。然后调用service.onCreate。至此,Service创建完毕。

二、Service的绑定1、 ContextImpl.bindServicepublicbooleanbindService(Intentservice,ServiceConnectionconn,intflags){//系统进程调用绑定服务或发送广播都会发出警告warnIfCallingFromSystemProcess();returnbindServiceCommon(service,conn,flags,null,mMainThread.getHandler(),null,getUser());}2、ContextImpl.bindServiceCommon

在分析一,主要判断入参Executor executor或UserHandle user哪个为null,总有一个为null,但最终都是调用了LoadedApk的getServiceDispatcherCommon函数来获取ServiceDispathcer类型sd。影响只是回调代码是在主线程执行,还是线程池。这里传入ActivityThread的H对象,意味着后续连接成功回调onServiceConnected是在主线程。

分析二:通过Binder机制调用AMS的bindIsolatedService函数。

privatebooleanbindServiceCommon(Intentservice,ServiceConnectionconn,intflags,StringinstanceName,Handlerhandler,Executorexecutor,UserHandleuser){//KeepthisinsyncwithDevicePolicyManager.bindDeviceAdminServiceAsUser.IServiceConnectionsd;if(conn==null){thrownewIllegalArgumentException("connectionisnull");}if(handler!=null&&executor!=null){thrownewIllegalArgumentException("HandlerandExecutorbothsupplied");}if(mPackageInfo!=null){if(executor!=null){//分析一:无论哪个分支,都是获得ServiceConnect的本地引用sd,两者最终都是//调用LoadedApk的getServiceDispatcherCommonsd=mPackageInfo.getServiceDispatcher(conn,getOuterContext(),executor,flags);}else{//正常使用走这个分支sd=mPackageInfo.getServiceDispatcher(conn,getOuterContext(),handler,flags);}}else{thrownewRuntimeException("Notsupportedinsystemcontext");}//检查compantandpackageisnull?validateServiceIntent(service);try{IBindertoken=getActivityToken();if(token==null&&(flags&BIND_AUTO_CREATE)==0&&mPackageInfo!=null&&mPackageInfo.getApplicationInfo().targetSdkVersion<.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH){flags|=BIND_WAIVE_PRIORITY;}service.prepareToLeaveProcess(this);//分析二:调用AMS.bindIsolatedServiceintres=ActivityManager.getService().bindIsolatedService(mMainThread.getApplicationThread(),getActivityToken(),service,service.resolveTypeIfNeeded(getContentResolver()),sd,flags,instanceName,getOpPackageName(),user.getIdentifier());if(res<0){thrownewSecurityException("Notallowedtobindtoservice"+service);}returnres!=0;}catch(RemoteExceptione){throwe.rethrowFromSystemServer();}}

IServiceConnection连接的创建会先从缓存中获取,避免每次都要新建。分析一:通过executor或handler创建ServiceDispatcher类型的sd,含有静态内部类InnerConnection的引用mIServiceConnection。继承自IServiceConnection.Stub,也就是InnerConnection是实现者,远程调用代理在其他进程,例如SystemServer进程中的ActiveService。

privateIServiceConnectiongetServiceDispatcherCommon(ServiceConnectionc,Contextcontext,Handlerhandler,Executorexecutor,intflags){synchronized(mServices){LoadedApk.ServiceDispatchersd=null;//从缓存获取ArrayMap<ServiceConnection,LoadedApk.ServiceDispatcher>map=mServices.get(context);if(map!=null){sd=map.get(c);}if(sd==null){//分析一:通过executor或handler创建ServiceDispatcherif(executor!=null){sd=newServiceDispatcher(c,context,executor,flags);}else{sd=newServiceDispatcher(c,context,handler,flags);}if(DEBUG)Slog.d(TAG,"Creatingnewdispatcher"+sd+"forconn"+c);if(map==null){map=newArrayMap<>();mServices.put(context,map);}map.put(c,sd);}else{sd.validate(context,handler,executor);}returnsd.getIServiceConnection();}}3、AMS.bindIsolatedService

AMS经过两次重载函数bindIsolatedService调用,简单检查相关合法性。然后调用ActiveService类型的mService的bindServiceLocked函数。

4、ActiveService.bindServiceLockedintbindServiceLocked(IApplicationThreadcaller,IBindertoken,Intentservice,StringresolvedType,finalIServiceConnectionconnection,intflags,StringinstanceName,StringcallingPackage,finalintuserId)throwsTransactionTooLargeException{//发起绑定service的app进程描述finalProcessRecordcallerApp=mAm.getRecordForAppLocked(caller);...ServiceLookupResultres=retrieveServiceLocked(service,instanceName,resolvedType,callingPackage,Binder.getCallingPid(),Binder.getCallingUid(),userId,true,callerFg,isBindExternal,allowInstant);...ServiceRecords=res.record;...//描述Service和应用程序进程之间的关联,内部维护Service、进程、IntentFilter以及所有绑定信息。AppBindRecordb=s.retrieveAppBindingLocked(service,callerApp);//描述应用程序与service建立的一次通信()ConnectionRecordc=newConnectionRecord(b,activity,connection,flags,clientLabel,clientIntent,callerApp.uid,callerApp.processName,callingPackage);IBinderbinder=connection.asBinder();s.addConnection(binder,c);b.connections.add(c);if(activity!=null){activity.addConnection(c);}b.client.connections.add(c);c.startAssociationIfNeeded();...//启动Service,可以参考Service的启动if((flags&Context.BIND_AUTO_CREATE)!=0){s.lastActivity=SystemClock.uptimeMillis();if(bringUpServiceLocked(s,service.getFlags(),callerFg,false,permissionsReviewRequired)!=null){return0;}}...//表示Service已启动,且已返回binder,可以通过binder访问接口if(s.app!=null&&b.intent.received){//Serviceisalreadyrunning,sowecanimmediately//publishtheconnection.try{//建立连接c.conn.connected(s.name,b.intent.binder,false);}catch(Exceptione){Slog.w(TAG,"Failuresendingservice"+s.shortInstanceName+"toconnection"+c.conn.asBinder()+"(in"+c.binding.client.processName+")",e);}//第一个绑定该Service的进程,且要重绑if(b.intent.apps.size()==1&&b.intent.doRebind){requestServiceBindingLocked(s,b.intent,callerFg,true);}}elseif(!b.intent.requested){//首次绑定,执行此次requestServiceBindingLocked(s,b.intent,callerFg,false);}...}

AppBindRecord 描述应用程序进程和Service的关联,包括谁绑定了Service的ProcessRecord,绑定信息IntentBindRecord,当前服务ServiceRecord,当前应用进程的所有连接记录connections。

5、requestServiceBindingLocked

调用了ApplicationThread的scheduleBindService函数。

privatefinalbooleanrequestServiceBindingLocked(ServiceRecordr,IntentBindRecordi,booleanexecInFg,booleanrebind)throwsTransactionTooLargeException{...r.app.thread.scheduleBindService(r,i.intent.getIntent(),rebind,r.app.getReportedProcState());...}6、ApplicationThread.scheduleBindService

将数据封装BindServiceData,发送个ActivityThread的H类型的mH处理。

publicfinalvoidscheduleBindService(IBindertoken,Intentintent,booleanrebind,intprocessState){updateProcessState(processState,false);BindServiceDatas=newBindServiceData();s.token=token;s.intent=intent;s.rebind=rebind;sendMessage(H.BIND_SERVICE,s);}7 、 H.handleMessagecaseBIND_SERVICE:handleBindService((BindServiceData)msg.obj);8、ActivityThread.handleBindService

handleBindService函数有两个分支,即是否重新绑定。

如果当前进程第一个与Service绑定,且调用过了onUbBinder方法,那么这里的data.rebind将为true,直接执行Service的onRebind函数即可。另外一种就是没有绑定过,那么需要执行Service的onBind函数。然后还要执行AMS的publishService函数。

privatevoidhandleBindService(BindServiceDatadata){Services=mServices.get(data.token);if(s!=null){...try{if(!data.rebind){IBinderbinder=s.onBind(data.intent);ActivityManager.getService().publishService(data.token,data.intent,binder);}else{s.onRebind(data.intent);ActivityManager.getService().serviceDoneExecuting(data.token,SERVICE_DONE_EXECUTING_ANON,0,0);}}catch(RemoteExceptionex){throwex.rethrowFromSystemServer();}...}}9、AMS.publishServicepublicvoidpublishService(IBindertoken,Intentintent,IBinderservice){//Refusepossibleleakedfiledescriptorsif(intent!=null&amp;&amp;intent.hasFileDescriptors()==true){thrownewIllegalArgumentException("FiledescriptorspassedinIntent");}synchronized(this){if(!(tokeninstanceofServiceRecord)){thrownewIllegalArgumentException("Invalidservicetoken");}mServices.publishServiceLocked((ServiceRecord)token,intent,service);}}10、ActiveService.publishServiceLocked

分析一:可见在第4步bindServiceLocked函数,IntentBindRecord对象的属性binder、requested、received都是false。

在ServiceRecord的所有连接记录connections中,通过intent查找对应之前已经保存的ConnectionRecord,并调用其IServiceConnection的connected函数。

在第2步的时候调用bindServiceCommon函数时,会创建ServiceDispatcher时,内部持有InnerConnection实例,这里的IServiceConnection代理引用指向该InnerConnection实例,这里会调用其connected函数。

voidpublishServiceLocked(ServiceRecordr,Intentintent,IBinderservice){finallongorigId=Binder.clearCallingIdentity();try{if(r!=null){Intent.FilterComparisonfilter=newIntent.FilterComparison(intent);IntentBindRecordb=r.bindings.get(filter);if(b!=null&amp;&amp;!b.received){//分析1b.binder=service;b.requested=true;b.received=true;ArrayMap&lt;IBinder,ArrayList&lt;ConnectionRecord&gt;&gt;connections=r.getConnections();for(intconni=connections.size()-1;conni&gt;=0;conni--){ArrayList&lt;ConnectionRecord&gt;clist=connections.valueAt(conni);for(inti=0;i&lt;clist.size();i++){ConnectionRecordc=clist.get(i);if(!filter.equals(c.binding.intent.intent)){...continue;}...try{c.conn.connected(r.name,service,false);}catch(Exceptione){Slog.w(TAG,"Failuresendingservice"+r.shortInstanceName+"toconnection"+c.conn.asBinder()+"(in"+c.binding.client.processName+")",e);}}}}serviceDoneExecutingLocked(r,mDestroyingServices.contains(r),false);}}finally{Binder.restoreCallingIdentity(origId);}}11、InnerConnection.connectedprivatestaticclassInnerConnectionextendsIServiceConnection.Stub{@UnsupportedAppUsagefinalWeakReference<LoadedApk.ServiceDispatcher>mDispatcher;InnerConnection(LoadedApk.ServiceDispatchersd){mDispatcher=newWeakReference<LoadedApk.ServiceDispatcher>(sd);}publicvoidconnected(ComponentNamename,IBinderservice,booleandead)throwsRemoteException{LoadedApk.ServiceDispatchersd=mDispatcher.get();if(sd!=null){sd.connected(name,service,dead);}}}12、ServiceDispatcher.connected

这里调用了 mActivityThread.post(new RunConnection(name, service, 0, dead)),执行RunConnection的run函数。这里的话run函数执行代码又回到了应用进程的主线程。

publicvoidconnected(ComponentNamename,IBinderservice,booleandead){if(mActivityExecutor!=null){mActivityExecutor.execute(newRunConnection(name,service,0,dead));}elseif(mActivityThread!=null){mActivityThread.post(newRunConnection(name,service,0,dead));}else{doConnected(name,service,dead);}}13、RunConnection.run

RunConnection是ServiceDispatcher的内部类,这里执行SD的doConnected函数。

publicvoidrun(){if(mCommand==0){doConnected(mName,mService,mDead);}elseif(mCommand==1){doDeath(mName,mService);}}14、ServiceDispatcher.doConnected

这里调用了ServiceConnection对象的onServiceConnected函数,也就是我们发起绑定,调用context.bindService的参数。

publicvoiddoConnected(ComponentNamename,IBinderservice,booleandead){...mConnection.onServiceConnected(name,service);...}

到此,Service的绑定流程分析完毕。

三、Service的Context

在第一节Service的启动流程最后函数调用了ActivityThread的handleCreateService函数。

privatevoidhandleCreateService(CreateServiceDatadata){unscheduleGcIdler();//应用的描述信息LoadedApkpackageInfo=getPackageInfoNoCheck(data.info.applicationInfo,data.compatInfo);Serviceservice=null;try{//分析一ContextImplcontext=ContextImpl.createAppContext(this,packageInfo);Applicationapp=packageInfo.makeApplication(false,mInstrumentation);java.lang.ClassLoadercl=packageInfo.getClassLoader();service=packageInfo.getAppFactory().instantiateService(cl,data.info.name,data.intent);context.getResources().addLoaders(app.getResources().getLoaders().toArray(newResourcesLoader[0]));//分析二context.setOuterContext(service);//分析三service.attach(context,this,data.info.name,data.token,app,ActivityManager.getService());service.onCreate();mServices.put(data.token,service);try{ActivityManager.getService().serviceDoneExecuting(data.token,SERVICE_DONE_EXECUTING_ANON,0,0);}catch(RemoteExceptione){throwe.rethrowFromSystemServer();}}catch(Exceptione){if(!mInstrumentation.onException(service,e)){thrownewRuntimeException("Unabletocreateservice"+data.info.name+":"+e.toString(),e);}}}

分析一:通过ContextImpl的静态函数createAppContext返回了一个ContextImpl类型的context。createAppContext又调用了重载函数createAppContext。直接新建了ContextImpl实例context,构造函数传递了ActivityThread类型的mainThread和LoadedApk类型的packageInfo。并给context设置了资源环境和是否Syetem属性。

staticContextImplcreateAppContext(ActivityThreadmainThread,LoadedApkpackageInfo){returncreateAppContext(mainThread,packageInfo,null);}staticContextImplcreateAppContext(ActivityThreadmainThread,LoadedApkpackageInfo,StringopPackageName){if(packageInfo==null)thrownewIllegalArgumentException("packageInfo");ContextImplcontext=newContextImpl(null,mainThread,packageInfo,null,null,null,null,0,null,opPackageName);context.setResources(packageInfo.getResources());context.mIsSystemOrSystemUiContext=isSystemOrSystemUI(context);returncontext;}

ContextImpl类有一个Context类型的mOuterContext属性,在构造函数时指向了自己。

回到handleCreateService函数的分析二,在创建好Service对象service之后,将service作为参数传递给了context.setOuterContext函数。Service本身继承自ContextWrapper,ContextWrapper又是Context的子类。这时候的setOuterContext函数将service设置给了context的mOuterContext属性。意味着当前上下文context持有当前新建的service引用。

在分析三,调用了service.attach函数,context并作为第一个参数被传入。attach函数又调用了attachBaseContext函数。

publicfinalvoidattach(Contextcontext,ActivityThreadthread,StringclassName,IBindertoken,Applicationapplication,ObjectactivityManager){attachBaseContext(context);mThread=thread;mClassName=className;mToken=token;mApplication=application;mActivityManager=(IActivityManager)activityManager;mStartCompatibility=getApplicationInfo().targetSdkVersion&lt;Build.VERSION_CODES.ECLAIR;setContentCaptureOptions(application.getContentCaptureOptions());}

attachBaseContext调用了父类ContextWrapper的attachBaseContext函数

@OverrideprotectedvoidattachBaseContext(ContextnewBase){super.attachBaseContext(newBase);if(newBase!=null){newBase.setContentCaptureOptions(getContentCaptureOptions());}}

ContextWrapper将一路传递过来的上下文base设置给你了mBase属性。

protectedvoidattachBaseContext(Contextbase){if(mBase!=null){thrownewIllegalStateException("Basecontextalreadyset");}mBase=base;}

也就是说,我们在启动Service时,会同时创建Service的上下文context,并将其存储到Service的父类ContextWrapper的mBases属性中,同时context也会有当前Service引用,存储在mOuterContext变量中。

关于“AndroidService启动绑定流程是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“AndroidService启动绑定流程是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

域名注册
购买VPS主机

您或许对下面这些文章有兴趣:                    本月吐槽辛苦排行榜

看贴要回贴有N种理由!看帖不回贴的后果你懂得的!


评论内容 (*必填):
(Ctrl + Enter提交)   

部落快速搜索栏

各类专题梳理

网站导航栏

X
返回顶部