您好,登錄后才能下訂單哦!
這篇文章主要介紹了Android Service啟動(dòng)綁定流程是什么的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Android Service啟動(dòng)綁定流程是什么文章都會(huì)有所收獲,下面我們一起來看看吧。
啟動(dòng)一個(gè)Service
,通常在Activity
調(diào)用startService
來啟動(dòng)。
@Override public ComponentName startService(Intent service) { return startServiceCommon(service, false, mUser); }
startServiceCommon
檢查intent
內(nèi)容是否合法,然后做一些離開當(dāng)前進(jìn)程的準(zhǔn)備操作。調(diào)用 ActivityManager.getService()
獲得AMS
的本地引用,并調(diào)用其startService
函數(shù)。
也就是說通過Binder
機(jī)制跨進(jìn)程通信調(diào)用了AMS
的startService
函數(shù)。
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()
的實(shí)現(xiàn)。
@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
函數(shù)獲取調(diào)用Pid
和Uid
,然后調(diào)用ActiveService
的startServiceLocked
函數(shù)。
@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
函數(shù),對一些合法性的檢查,例如前臺(tái)Service
的權(quán)限、限制性后臺(tái)Service
進(jìn)行延遲運(yùn)行(standby)
。并將要啟動(dòng)的信息封裝成ServiceRecord
。然后調(diào)用了startServiceInnerLocked
函數(shù)。
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) { //獲取調(diào)用Service的應(yīng)用程序進(jìn)程描述 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); if (callerApp == null) { ... } callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND; } else { callerFg = true; } //檢索ServiceRecord,包括同應(yīng)用和其他應(yīng)用 ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg, false, false); ... //要啟動(dòng)的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; }
調(diào)用了bringUpServiceLocked
函數(shù),會(huì)將ServiceRecord
添加到ServiceMap
類型的smap
集合,進(jìn)行緩存。
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; }
分析一:首次啟動(dòng)Service
時(shí),在執(zhí)行bringUpServiceLocked
函數(shù),ServiceRecord
是屬于新創(chuàng)建的,而非從AMS
的緩存mServices
中檢索而來,所以此時(shí)的ServiceRecord
的ProcessRecord
類型app
和IApplicationThread
類型thread
都是null。只有啟動(dòng)過后的ServiceRecord
才有值,才會(huì)執(zhí)行sendServiceArgsLocked
函數(shù),重復(fù)調(diào)用Service
的生命周期onStartCommand
,而不調(diào)用onCreate
函數(shù)。
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { //分析一:未啟動(dòng)過的ServiceRecord兩者都是null,重復(fù)啟動(dòng)會(huì)執(zhí)行該函數(shù), //會(huì)重復(fù)調(diào)用service的onStartCommand函數(shù)。 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所在進(jìn)程的ProcessRecord。ProcessList=>MyProcessMap=》會(huì)緩存已創(chuàng)建過進(jìn)程的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); //啟動(dòng)服務(wù) 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所在的進(jìn)程未啟動(dòng),通過AMS啟動(dòng)該進(jìn)程,可以參考應(yīng)用進(jìn)程的啟動(dòng)流程 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; } } //等待進(jìn)程啟動(dòng)完畢重啟啟動(dòng) if (!mPendingServices.contains(r)) { mPendingServices.add(r); } ... return null; }
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { //將ProcessRecord設(shè)置給ServiceRecord r.setProcess(app); //登記當(dāng)ServiceRecord到ProcessRecordd的數(shù)組mServices,表示Service已經(jīng)啟動(dòng)(實(shí)際未啟動(dòng)) 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; } //會(huì)調(diào)用Service的onStartCommand函數(shù) sendServiceArgsLocked(r, execInFg, true); ... }
通過ProcessRecord
對象的IApplicationThread
引用,通過Binder
機(jī)制調(diào)用了應(yīng)用程序的ApplicationThread
的scheduleCreateService
函數(shù)。
將ServiceInfo
等相關(guān)信息封裝到CreateServiceData
中,并發(fā)送給ActivityThread
的H
類型的mH
對象。
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); }
調(diào)用了ActivityThread
的handleCreateService
函數(shù)。
case CREATE_SERVICE: handleCreateService((CreateServiceData)msg.obj); break;
private void handleCreateService(CreateServiceData data) { ... //獲取當(dāng)前應(yīng)用的描述信息LoadedApk LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { //創(chuàng)建Service的上下問文 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); //獲取當(dāng)前應(yīng)用Applcation對象 Application app = packageInfo.makeApplication(false, mInstrumentation); //通過反射創(chuàng)建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()); //調(diào)用Service的生命周期onCreate函數(shù),意味Service創(chuàng)建完畢 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
創(chuàng)建Service
的上下文context
,通過packageInfo.getAppFactory().instantiateService
反射獲得當(dāng)前Service
對象service
,將context
與service
相互綁定。然后調(diào)用service.onCreate
。至此,Service
創(chuàng)建完畢。
public boolean bindService(Intent service, ServiceConnection conn, int flags) { //系統(tǒng)進(jìn)程調(diào)用綁定服務(wù)或發(fā)送廣播都會(huì)發(fā)出警告 warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, getUser()); }
在分析一,主要判斷入?yún)?code>Executor executor或UserHandle user
哪個(gè)為null
,總有一個(gè)為null
,但最終都是調(diào)用了LoadedApk
的getServiceDispatcherCommon
函數(shù)來獲取ServiceDispathcer
類型sd。影響只是回調(diào)代碼是在主線程執(zhí)行,還是線程池。這里傳入ActivityThread
的H
對象,意味著后續(xù)連接成功回調(diào)onServiceConnected
是在主線程。
分析二:通過Binder機(jī)制調(diào)用AMS
的bindIsolatedService
函數(shù)。
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) {//分析一:無論哪個(gè)分支,都是獲得ServiceConnect的本地引用sd,兩者最終都是 //調(diào)用LoadedApk的getServiceDispatcherCommon sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags); } else { //正常使用走這個(gè)分支 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); //分析二:調(diào)用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
連接的創(chuàng)建會(huì)先從緩存中獲取,避免每次都要新建。分析一:通過executor
或handler
創(chuàng)建ServiceDispatcher
類型的sd
,含有靜態(tài)內(nèi)部類InnerConnection
的引用mIServiceConnection
。繼承自IServiceConnection.Stub
,也就是InnerConnection
是實(shí)現(xiàn)者,遠(yuǎn)程調(diào)用代理在其他進(jìn)程,例如SystemServer
進(jìn)程中的ActiveService
。
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創(chuàng)建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
經(jīng)過兩次重載函數(shù)bindIsolatedService
調(diào)用,簡單檢查相關(guān)合法性。然后調(diào)用ActiveService
類型的mService
的bindServiceLocked
函數(shù)。
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String instanceName, String callingPackage, final int userId) throws TransactionTooLargeException { //發(fā)起綁定service的app進(jìn)程描述 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和應(yīng)用程序進(jìn)程之間的關(guān)聯(lián),內(nèi)部維護(hù)Service、進(jìn)程、IntentFilter以及所有綁定信息。 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); //描述應(yīng)用程序與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(); ... //啟動(dòng)Service,可以參考Service的啟動(dòng) if ((flags&Context.BIND_AUTO_CREATE) != 0) { s.lastActivity = SystemClock.uptimeMillis(); if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, permissionsReviewRequired) != null) { return 0; } } ... //表示Service已啟動(dòng),且已返回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); } //第一個(gè)綁定該Service的進(jìn)程,且要重綁 if (b.intent.apps.size() == 1 && b.intent.doRebind) { requestServiceBindingLocked(s, b.intent, callerFg, true); } } else if (!b.intent.requested) {//首次綁定,執(zhí)行此次 requestServiceBindingLocked(s, b.intent, callerFg, false); } ... }
AppBindRecord
描述應(yīng)用程序進(jìn)程和Service
的關(guān)聯(lián),包括誰綁定了Service
的ProcessRecord
,綁定信息IntentBindRecord
,當(dāng)前服務(wù)ServiceRecord
,當(dāng)前應(yīng)用進(jìn)程的所有連接記錄connections
。
調(diào)用了ApplicationThread
的scheduleBindService
函數(shù)。
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()); ... }
將數(shù)據(jù)封裝 BindServiceData
,發(fā)送個(gè)ActivityThread
的H類型的mH
處理。
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); }
case BIND_SERVICE: handleBindService((BindServiceData)msg.obj);
handleBindService
函數(shù)有兩個(gè)分支,即是否重新綁定。
如果當(dāng)前進(jìn)程第一個(gè)與Service
綁定,且調(diào)用過了onUbBinder
方法,那么這里的data.rebind
將為true
,直接執(zhí)行Service
的onRebind
函數(shù)即可。另外一種就是沒有綁定過,那么需要執(zhí)行Service
的onBind
函數(shù)。然后還要執(zhí)行AMS
的publishService
函數(shù)。
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(); } ... } }
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
函數(shù),IntentBindRecord
對象的屬性binder
、requested
、received
都是false
。
在ServiceRecord
的所有連接記錄connections
中,通過intent
查找對應(yīng)之前已經(jīng)保存的ConnectionRecord
,并調(diào)用其IServiceConnection
的connected
函數(shù)。
在第2步的時(shí)候調(diào)用bindServiceCommon
函數(shù)時(shí),會(huì)創(chuàng)建ServiceDispatcher
時(shí),內(nèi)部持有InnerConnection
實(shí)例,這里的IServiceConnection
代理引用指向該InnerConnection
實(shí)例,這里會(huì)調(diào)用其connected
函數(shù)。
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); } }
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); } } }
這里調(diào)用了 mActivityThread.post(new RunConnection(name, service, 0, dead))
,執(zhí)行RunConnection
的run
函數(shù)。這里的話run函數(shù)執(zhí)行代碼又回到了應(yīng)用進(jìn)程的主線程。
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
的內(nèi)部類,這里執(zhí)行SD
的doConnected
函數(shù)。
public void run() { if (mCommand == 0) { doConnected(mName, mService, mDead); } else if (mCommand == 1) { doDeath(mName, mService); } }
這里調(diào)用了ServiceConnection
對象的onServiceConnected
函數(shù),也就是我們發(fā)起綁定,調(diào)用context.bindService
的參數(shù)。
public void doConnected(ComponentName name, IBinder service, boolean dead) { ... mConnection.onServiceConnected(name, service); ... }
到此,Service
的綁定流程分析完畢。
在第一節(jié)Service的啟動(dòng)流程最后函數(shù)調(diào)用了ActivityThread
的handleCreateService
函數(shù)。
private void handleCreateService(CreateServiceData data) { unscheduleGcIdler(); //應(yīng)用的描述信息 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
的靜態(tài)函數(shù)createAppContext
返回了一個(gè)ContextImpl
類型的context
。createAppContext
又調(diào)用了重載函數(shù)createAppContext
。直接新建了ContextImpl實(shí)例context,構(gòu)造函數(shù)傳遞了ActivityThread類型的mainThread和LoadedApk類型的packageInfo。并給context設(shè)置了資源環(huán)境和是否Syetem屬性。
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
類有一個(gè)Context
類型的mOuterContext
屬性,在構(gòu)造函數(shù)時(shí)指向了自己。
回到handleCreateService
函數(shù)的分析二,在創(chuàng)建好Service
對象service
之后,將service
作為參數(shù)傳遞給了context.setOuterContext
函數(shù)。Service
本身繼承自ContextWrapper
,ContextWrapper
又是Context
的子類。這時(shí)候的setOuterContext
函數(shù)將service
設(shè)置給了context
的mOuterContext
屬性。意味著當(dāng)前上下文context
持有當(dāng)前新建的service
引用。
在分析三,調(diào)用了service.attach
函數(shù),context
并作為第一個(gè)參數(shù)被傳入。attach
函數(shù)又調(diào)用了attachBaseContext
函數(shù)。
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
調(diào)用了父類ContextWrapper
的attachBaseContext
函數(shù)
@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(newBase); if (newBase != null) { newBase.setContentCaptureOptions(getContentCaptureOptions()); } }
ContextWrapper
將一路傳遞過來的上下文base
設(shè)置給你了mBase
屬性。
protected void attachBaseContext(Context base) { if (mBase != null) { throw new IllegalStateException("Base context already set"); } mBase = base; }
也就是說,我們在啟動(dòng)Service
時(shí),會(huì)同時(shí)創(chuàng)建Service
的上下文context
,并將其存儲(chǔ)到Service的父類ContextWrapper
的mBases
屬性中,同時(shí)context
也會(huì)有當(dāng)前Service引用,存儲(chǔ)在mOuterContext
變量中。
關(guān)于“Android Service啟動(dòng)綁定流程是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Android Service啟動(dòng)綁定流程是什么”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。