时间:2023-03-09来源:系统城装机大师作者:佚名
本文基于Android 11,参考《Android进阶解密》一书资料。了解Service的启动和绑定流程,以及Service的Context创建过程。
由于基于分析流程,忽略很多细节分支。各位在看源码的时候,要尽可能忽略细节,分析整体流程之后,还有精力的话再去看细节。例如有些属性是在后面赋值的,如果在前面追究,难哦。
另:阅读这种流程需要很大的耐心和毅力。建议在心情愉悦想要学习的时候搭配源码一起食用。
启动一个Service
,通常在Activity
调用startService
来启动。
1 2 3 4 |
@Override public ComponentName startService(Intent service) { return startServiceCommon(service, false , mUser); } |
startServiceCommon
检查intent
内容是否合法,然后做一些离开当前进程的准备操作。调用 ActivityManager.getService()
获得AMS
的本地引用,并调用其startService
函数。
也就是说通过Binder
机制跨进程通信调用了AMS
的startService
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) { try { //检查intent 的compant和package是否合法 validateServiceIntent(service); ... ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), requireForeground, getOpPackageName(), getAttributionTag(), user.getIdentifier()); ... return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } |
通过 ActivityManager.getService()
的实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@UnsupportedAppUsage public static IActivityManager getService() { return IActivityManagerSingleton.get(); } @UnsupportedAppUsage private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } }; |
AMS.startService
函数获取调用Pid
和Uid
,然后调用ActiveService
的startServiceLocked
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
@Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, boolean requireForeground, String callingPackage, String callingFeatureId, int userId) throws TransactionTooLargeException { ... synchronized ( this ) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res; try { res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, requireForeground, callingPackage, callingFeatureId, userId); } finally { Binder.restoreCallingIdentity(origId); } return res; } } |
ActiveService.startServiceLock
函数,对一些合法性的检查,例如前台Service
的权限、限制性后台Service
进行延迟运行(standby)
。并将要启动的信息封装成ServiceRecord
。然后调用了startServiceInnerLocked
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, @Nullable String callingFeatureId, final int userId) throws TransactionTooLargeException { return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired, callingPackage, callingFeatureId, userId, false ); } ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, @Nullable String callingFeatureId, final int userId, boolean allowBackgroundActivityStarts) throws TransactionTooLargeException { final boolean callerFg; if (caller != null ) { //获取调用Service的应用程序进程描述 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); if (callerApp == null ) { ... } callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND; } else { callerFg = true ; } //检索ServiceRecord,包括同应用和其他应用 ServiceLookupResult res = retrieveServiceLocked(service, null , resolvedType, callingPackage, callingPid, callingUid, userId, true , callerFg, false , false ); ... //要启动的ServiceRecord ServiceRecord r = res.record; ... r.lastActivity = SystemClock.uptimeMillis(); r.startRequested = true ; r.delayedStop = false ; r.fgRequired = fgRequired; r.pendingStarts.add( new ServiceRecord.StartItem(r, false , r.makeNextStartId(), service, neededGrants, callingUid)); ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); ... return cmp; } |
调用了bringUpServiceLocked
函数,会将ServiceRecord
添加到ServiceMap
类型的smap
集合,进行缓存。
1 2 3 4 5 6 7 8 |
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { r.callStart = false ; ... String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false , false ); ... return r.name; } |
分析一:首次启动Service
时,在执行bringUpServiceLocked
函数,ServiceRecord
是属于新创建的,而非从AMS
的缓存mServices
中检索而来,所以此时的ServiceRecord
的ProcessRecord
类型app
和IApplicationThread
类型thread
都是null。只有启动过后的ServiceRecord
才有值,才会执行sendServiceArgsLocked
函数,重复调用Service
的生命周期onStartCommand
,而不调用onCreate
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { //分析一:未启动过的ServiceRecord两者都是null,重复启动会执行该函数, //会重复调用service的onStartCommand函数。 if (r.app != null && r.app.thread != null ) { sendServiceArgsLocked(r, execInFg, false ); return null ; } ... final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0 ; final String procName = r.processName; HostingRecord hostingRecord = new HostingRecord( "service" , r.instanceName); ProcessRecord app; if (!isolated) { ////通过AMS获取service所在进程的ProcessRecord。ProcessList=>MyProcessMap=》会缓存已创建过进程的ProcessRecord app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false ); if (app != null && app.thread != null ) { try { app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats); //启动服务 realStartServiceLocked(r, app, execInFg); return null ; } catch (TransactionTooLargeException e) { throw e; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e); } } } //如果service所在的进程未启动,通过AMS启动该进程,可以参考应用进程的启动流程 if (app == null && !permissionsReviewRequired) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true , intentFlags, hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false , isolated, false )) == null ) {; bringDownServiceLocked(r); return msg; } if (isolated) { r.isolatedProc = app; } } //等待进程启动完毕重启启动 if (!mPendingServices.contains(r)) { mPendingServices.add(r); } ... return null ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { //将ProcessRecord设置给ServiceRecord r.setProcess(app); //登记当ServiceRecord到ProcessRecordd的数组mServices,表示Service已经启动(实际未启动) final boolean newService = app.startService(r); boolean created = false ; try { ... app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), app.getReportedProcState()); ... } catch (DeadObjectException e) { Slog.w(TAG, "Application dead when creating service " + r); mAm.appDiedLocked(app, "Died when creating service" ); throw e; } //会调用Service的onStartCommand函数 sendServiceArgsLocked(r, execInFg, true ); ... } |
通过ProcessRecord
对象的IApplicationThread
引用,通过Binder
机制调用了应用程序的ApplicationThread
的scheduleCreateService
函数。
将ServiceInfo
等相关信息封装到CreateServiceData
中,并发送给ActivityThread
的H
类型的mH
对象。
1 2 3 4 5 6 7 8 9 |
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) { updateProcessState(processState, false ); CreateServiceData s = new CreateServiceData(); s.token = token; s.info = info; s.compatInfo = compatInfo; sendMessage(H.CREATE_SERVICE, s); } |
调用了ActivityThread
的handleCreateService
函数。
1 2 3 |
case CREATE_SERVICE: handleCreateService((CreateServiceData)msg.obj); break ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
private void handleCreateService(CreateServiceData data) { ... //获取当前应用的描述信息LoadedApk LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null ; try { //创建Service的上下问文 ContextImpl context = ContextImpl.createAppContext( this , packageInfo); //获取当前应用Applcation对象 Application app = packageInfo.makeApplication( false , mInstrumentation); //通过反射创建Service对象 java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); //初始化资源 context.getResources().addLoaders( app.getResources().getLoaders().toArray( new ResourcesLoader[ 0 ])); //context 与service相互绑定 context.setOuterContext(service); service.attach(context, this , data.info.name, data.token, app, ActivityManager.getService()); //调用Service的生命周期onCreate函数,意味Service创建完毕 service.onCreate(); //缓存Service mServices.put(data.token, service); try { ActivityManager.getService().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0 , 0 ); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } } |
通过ContextImpl.createAppContext
创建Service
的上下文context
,通过packageInfo.getAppFactory().instantiateService
反射获得当前Service
对象service
,将context
与service
相互绑定。然后调用service.onCreate
。至此,Service
创建完毕。
1 2 3 4 5 6 |
public boolean bindService(Intent service, ServiceConnection conn, int flags) { //系统进程调用绑定服务或发送广播都会发出警告 warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, null , mMainThread.getHandler(), null , getUser()); } |
在分析一,主要判断入参Executor executor
或UserHandle user
哪个为null
,总有一个为null
,但最终都是调用了LoadedApk
的getServiceDispatcherCommon
函数来获取ServiceDispathcer
类型sd。影响只是回调代码是在主线程执行,还是线程池。这里传入ActivityThread
的H
对象,意味着后续连接成功回调onServiceConnected
是在主线程。
分析二:通过Binder机制调用AMS
的bindIsolatedService
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, String instanceName, Handler handler, Executor executor, UserHandle user) { // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser. IServiceConnection sd; if (conn == null ) { throw new IllegalArgumentException( "connection is null" ); } if (handler != null && executor != null ) { throw new IllegalArgumentException( "Handler and Executor both supplied" ); } if (mPackageInfo != null ) { if (executor != null ) { //分析一:无论哪个分支,都是获得ServiceConnect的本地引用sd,两者最终都是 //调用LoadedApk的getServiceDispatcherCommon sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags); } else { //正常使用走这个分支 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); } } else { throw new RuntimeException( "Not supported in system context" ); } //检查compant and package is null ? validateServiceIntent(service); try { IBinder token = getActivityToken(); if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null && mPackageInfo.getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { flags |= BIND_WAIVE_PRIORITY; } service.prepareToLeaveProcess( this ); //分析二:调用AMS.bindIsolatedService int res = ActivityManager.getService().bindIsolatedService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, instanceName, getOpPackageName(), user.getIdentifier()); if (res < 0 ) { throw new SecurityException( "Not allowed to bind to service " + service); } return res != 0 ; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } |
IServiceConnection
连接的创建会先从缓存中获取,避免每次都要新建。分析一:通过executor
或handler
创建ServiceDispatcher
类型的sd
,含有静态内部类InnerConnection
的引用mIServiceConnection
。继承自IServiceConnection.Stub
,也就是InnerConnection
是实现者,远程调用代理在其他进程,例如SystemServer
进程中的ActiveService
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c, Context context, Handler handler, Executor executor, int flags) { synchronized (mServices) { LoadedApk.ServiceDispatcher sd = null ; //从缓存获取 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); if (map != null ) { sd = map.get(c); } if (sd == null ) { //分析一:通过executor或handler创建ServiceDispatcher if (executor != null ) { sd = new ServiceDispatcher(c, context, executor, flags); } else { sd = new ServiceDispatcher(c, context, handler, flags); } if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c); if (map == null ) { map = new ArrayMap<>(); mServices.put(context, map); } map.put(c, sd); } else { sd.validate(context, handler, executor); } return sd.getIServiceConnection(); } } |
AMS
经过两次重载函数bindIsolatedService
调用,简单检查相关合法性。然后调用ActiveService
类型的mService
的bindServiceLocked
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String instanceName, String callingPackage, final int userId) throws TransactionTooLargeException { //发起绑定service的app进程描述 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); ... ServiceLookupResult res = retrieveServiceLocked(service, instanceName, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), userId, true , callerFg, isBindExternal, allowInstant); ... ServiceRecord s = res.record; ... //描述Service和应用程序进程之间的关联,内部维护Service、进程、IntentFilter以及所有绑定信息。 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); //描述应用程序与service建立的一次通信(绑定) ConnectionRecord c = new ConnectionRecord(b, activity, connection, flags, clientLabel, clientIntent, callerApp.uid, callerApp.processName, callingPackage); IBinder binder = 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 ) { return 0 ; } } ... //表示Service已启动,且已返回binder,可以通过binder访问接口 if (s.app != null && b.intent.received) { // Service is already running, so we can immediately // publish the connection. try { //建立连接 c.conn.connected(s.name, b.intent.binder, false ); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + s.shortInstanceName + " to connection " + 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 ); } } else if (!b.intent.requested) { //首次绑定,执行此次 requestServiceBindingLocked(s, b.intent, callerFg, false ); } ... } |
AppBindRecord
描述应用程序进程和Service
的关联,包括谁绑定了Service
的ProcessRecord
,绑定信息IntentBindRecord
,当前服务ServiceRecord
,当前应用进程的所有连接记录connections
。
调用了ApplicationThread
的scheduleBindService
函数。
1 2 3 4 5 6 |
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean execInFg, boolean rebind) throws TransactionTooLargeException { ... r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.getReportedProcState()); ... } |
将数据封装 BindServiceData
,发送个ActivityThread
的H类型的mH
处理。
1 2 3 4 5 6 7 8 9 |
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind, int processState) { updateProcessState(processState, false ); BindServiceData s = new BindServiceData(); s.token = token; s.intent = intent; s.rebind = rebind; sendMessage(H.BIND_SERVICE, s); } |
1 2 |
case BIND_SERVICE: handleBindService((BindServiceData)msg.obj); |
handleBindService
函数有两个分支,即是否重新绑定。
如果当前进程第一个与Service
绑定,且调用过了onUbBinder
方法,那么这里的data.rebind
将为true
,直接执行Service
的onRebind
函数即可。另外一种就是没有绑定过,那么需要执行Service
的onBind
函数。然后还要执行AMS
的publishService
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
private void handleBindService(BindServiceData data) { Service s = mServices.get(data.token); if (s != null ) { ... try { if (!data.rebind) { IBinder binder = 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 (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ... } } |
1 2 3 4 5 6 7 8 9 10 11 12 |
public void publishService(IBinder token, Intent intent, IBinder service) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors() == true ) { throw new IllegalArgumentException( "File descriptors passed in Intent" ); } synchronized ( this ) { if (!(token instanceof ServiceRecord)) { throw new IllegalArgumentException( "Invalid service token" ); } mServices.publishServiceLocked((ServiceRecord)token, intent, service); } } |
分析一:可见在第4步bindServiceLocked
函数,IntentBindRecord
对象的属性binder
、requested
、received
都是false
。
在ServiceRecord
的所有连接记录connections
中,通过intent
查找对应之前已经保存的ConnectionRecord
,并调用其IServiceConnection
的connected
函数。
在第2步的时候调用bindServiceCommon
函数时,会创建ServiceDispatcher
时,内部持有InnerConnection
实例,这里的IServiceConnection
代理引用指向该InnerConnection
实例,这里会调用其connected
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) { final long origId = Binder.clearCallingIdentity(); try { if (r != null ) { Intent.FilterComparison filter = new Intent.FilterComparison(intent); IntentBindRecord b = r.bindings.get(filter); if (b != null && !b.received) { //分析1 b.binder = service; b.requested = true ; b.received = true ; ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); for ( int conni = connections.size() - 1 ; conni >= 0 ; conni--) { ArrayList<ConnectionRecord> clist = connections.valueAt(conni); for ( int i= 0 ; i<clist.size(); i++) { ConnectionRecord c = clist.get(i); if (!filter.equals(c.binding.intent.intent)) { ... continue ; } ... try { c.conn.connected(r.name, service, false ); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + r.shortInstanceName + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")" , e); } } } } serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false ); } } finally { Binder.restoreCallingIdentity(origId); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private static class InnerConnection extends IServiceConnection.Stub { @UnsupportedAppUsage final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; InnerConnection(LoadedApk.ServiceDispatcher sd) { mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd); } public void connected(ComponentName name, IBinder service, boolean dead) throws RemoteException { LoadedApk.ServiceDispatcher sd = mDispatcher.get(); if (sd != null ) { sd.connected(name, service, dead); } } } |
这里调用了 mActivityThread.post(new RunConnection(name, service, 0, dead))
,执行RunConnection
的run
函数。这里的话run函数执行代码又回到了应用进程的主线程。
1 2 3 4 5 6 7 8 9 |
public void connected(ComponentName name, IBinder service, boolean dead) { if (mActivityExecutor != null ) { mActivityExecutor.execute( new RunConnection(name, service, 0 , dead)); } else if (mActivityThread != null ) { mActivityThread.post( new RunConnection(name, service, 0 , dead)); } else { doConnected(name, service, dead); } } |
RunConnection
是ServiceDispatcher
的内部类,这里执行SD
的doConnected
函数。
1 2 3 4 5 6 7 |
public void run() { if (mCommand == 0 ) { doConnected(mName, mService, mDead); } else if (mCommand == 1 ) { doDeath(mName, mService); } } |
这里调用了ServiceConnection
对象的onServiceConnected
函数,也就是我们发起绑定,调用context.bindService
的参数。
1 2 3 4 5 |
public void doConnected(ComponentName name, IBinder service, boolean dead) { ... mConnection.onServiceConnected(name, service); ... } |
到此,Service
的绑定流程分析完毕。
在第一节Service的启动流程最后函数调用了ActivityThread
的handleCreateService
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
private void handleCreateService(CreateServiceData data) { unscheduleGcIdler(); //应用的描述信息 LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null ; try { //分析一 ContextImpl context = ContextImpl.createAppContext( this , packageInfo); Application app = packageInfo.makeApplication( false , mInstrumentation); java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); context.getResources().addLoaders( app.getResources().getLoaders().toArray( new ResourcesLoader[ 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 (RemoteException e) { throw e.rethrowFromSystemServer(); } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } } |
分析一:通过ContextImpl
的静态函数createAppContext
返回了一个ContextImpl
类型的context
。createAppContext
又调用了重载函数createAppContext
。直接新建了ContextImpl实例context,构造函数传递了ActivityThread类型的mainThread和LoadedApk类型的packageInfo。并给context设置了资源环境和是否Syetem属性。
1 2 3 4 5 6 7 8 9 10 11 12 |
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { return createAppContext(mainThread, packageInfo, null ); } static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo, String opPackageName) { if (packageInfo == null ) throw new IllegalArgumentException( "packageInfo" ); ContextImpl context = new ContextImpl( null , mainThread, packageInfo, null , null , null , null , 0 , null , opPackageName); context.setResources(packageInfo.getResources()); context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context); return context; } |
ContextImpl
类有一个Context
类型的mOuterContext
属性,在构造函数时指向了自己。
回到handleCreateService
函数的分析二,在创建好Service
对象service
之后,将service
作为参数传递给了context.setOuterContext
函数。Service
本身继承自ContextWrapper
,ContextWrapper
又是Context
的子类。这时候的setOuterContext
函数将service
设置给了context
的mOuterContext
属性。意味着当前上下文context
持有当前新建的service
引用。
在分析三,调用了service.attach
函数,context
并作为第一个参数被传入。attach
函数又调用了attachBaseContext
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public final void attach( Context context, ActivityThread thread, String className, IBinder token, Application application, Object activityManager) { attachBaseContext(context); mThread = thread; mClassName = className; mToken = token; mApplication = application; mActivityManager = (IActivityManager)activityManager; mStartCompatibility = getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.ECLAIR; setContentCaptureOptions(application.getContentCaptureOptions()); } |
attachBaseContext
调用了父类ContextWrapper
的attachBaseContext
函数
1 2 3 4 5 6 7 |
@Override protected void attachBaseContext(Context newBase) { super .attachBaseContext(newBase); if (newBase != null ) { newBase.setContentCaptureOptions(getContentCaptureOptions()); } } |
ContextWrapper
将一路传递过来的上下文base
设置给你了mBase
属性。
1 2 3 4 5 6 |
protected void attachBaseContext(Context base) { if (mBase != null ) { throw new IllegalStateException( "Base context already set" ); } mBase = base; } |
也就是说,我们在启动Service
时,会同时创建Service
的上下文context
,并将其存储到Service的父类ContextWrapper
的mBases
属性中,同时context
也会有当前Service引用,存储在mOuterContext
变量中。
Service
的启动和绑定从AMS
转移到ActiveService
Service
的启动,会先判断进程是否创建,提前启动进程,再启动自己。Service
重复启动,会重复调用onStratCommand
及后续生命周期函数。Service
的绑定,会先走一趟Service
的启动流程,再绑定。SytemServer
进程(AMS、ActiveService)
的交互式通过Binder机制进行,通过AIDL
各持有双方接口。应用进程通过H对象,将现成重新切回主线程(所有应用夸进程通信应如此)。Service
在应用和AMS
两边都会做缓存,以便快速在找到使用。应用程序存储在ArrayMap<IBinder, Service>
类型的mServices
;ActiveService
则是ArraySet<ServiceRecord>
类型的mServices
。2024-07-07
Java框架如何实现非阻塞式编程?2023-03-11
Android Jetpack 组件LiveData源码解析2023-03-11
hbuilderx设置Firefox浏览器安装路径教程 hbuilderx怎么设置Firefox浏览器安装路径?一、AVL树的概念 二、AVL树节点的定义 三、AVL树的插入 四、AVL树的旋转 1.左单旋 2.右单旋 3.左右双旋 4.右左双旋 五、进行验证 六、AVLTree的性能...
2023-03-09