基于Android U
ContextImpl到AMS的调用过程

要启动Service,我们会调用startService()方法,它在ContextWrapper中实现。
1 2 3 4
| frameworks/base/core/java/android/content/ContextWrapper.java public @Nullable ComponentName startService(Intent service) { return mBase.startService(service); }
|
mBase指的是ContextImpl,Activity的attach()方法中将ContextImpl赋值给ContextWrapper的成员变量mBase。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| frameworks/base/core/java/android/app/ContextImpl.java public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, false, mUser); }
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this); ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), requireForeground, getOpPackageName(), getAttributionTag(), user.getIdentifier()); ... return cn; } catch (RemoteException e) { ... } }
|
在startService()方法中会返回startServiceCommon()方法,在startServiceCommon()方法中会在注释1处调用AMS的代理IActivityManager的startService()方法,最终调用的是AMS的startService()方法。
ActivityThread启动Service
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
| frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java private ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, boolean requireForeground, String callingPackage, String callingFeatureId, int userId, boolean isSdkSandboxService, int sdkSandboxClientAppUid, String sdkSandboxClientAppPackage, String instanceName) throws TransactionTooLargeException { ... final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res; try { ... synchronized (this) { res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, requireForeground, callingPackage, callingFeatureId, userId, isSdkSandboxService, sdkSandboxClientAppUid, sdkSandboxClientAppPackage, instanceName); } } finally { ... } return res; }
|
注释1处调用mServices的startServiceLocked()方法,mServices的类型是ActiveServices。
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
| frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, @Nullable String callingFeatureId, final int userId, BackgroundStartPrivileges backgroundStartPrivileges, boolean isSdkSandboxService, int sdkSandboxClientAppUid, String sdkSandboxClientAppPackage, String instanceName) throws TransactionTooLargeException { ... ServiceLookupResult res = retrieveServiceLocked(service, instanceName, isSdkSandboxService, sdkSandboxClientAppUid, sdkSandboxClientAppPackage, resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg, false, false, null, false); ... ServiceRecord r = res.record; ... final ComponentName realResult = startServiceInnerLocked(r, service, callingUid, callingPid, callingProcessName, callingProcessState, fgRequired, callerFg, backgroundStartPrivileges, callingPackage); if (res.aliasComponent != null && !realResult.getPackageName().startsWith("!") && !realResult.getPackageName().startsWith("?")) { return res.aliasComponent; } else { return realResult; } }
|
注释1处的retrieveServiceLocked()方法会查找是否有与参数service对应的ServiceRecord,如果没有找到,就会调用PackageManagerService去获取参数service对应的Service信息,并封装到ServiceRecord中,最后将ServiceRecord封装为ServiceLookupResult返回。其中ServiceRecord用于描述一个Service,和ActivityRecord类似。
在注释2处通过注释1处返回的ServiceLookupResult得到参数service对应的ServiceRecord,并传入到注释3处的startServiceInnerLocked()方法中。
1 2 3 4 5 6 7 8 9 10 11 12
| frameworks/base/services/core/java/com/android/server/am/ActiveServices.java private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service, int callingUid, int callingPid, String callingProcessName, int callingProcessState, boolean fgRequired, boolean callerFg, BackgroundStartPrivileges backgroundStartPrivileges, String callingPackage) throws TransactionTooLargeException { ... ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting, callingUid, callingProcessName, callingProcessState, wasStartRequested, callingPackage); return cmp; }
|
继续调用startServiceInnerLocked()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting, int callingUid, String callingProcessName, int callingProcessState, boolean wasStartRequested, String callingPackage) throws TransactionTooLargeException { ... String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false , false , false , true ); ... if (error != null) { return new ComponentName("!!", error); } ... return r.name; }
|
注释1处调用了bringUpServiceLocked()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13
| frameworks/base/services/core/java/com/android/server/am/ActiveServices.java private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen, boolean enqueueOomAdj) throws TransactionTooLargeException { try { ... return bringUpServiceInnerLocked(r, intentFlags, execInFg, whileRestarting, permissionsReviewRequired, packageFrozen, enqueueOomAdj); } finally { ... } }
|
调用bringUpServiceInnerLocked()。
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
| frameworks/base/services/core/java/com/android/server/am/ActiveServices.java private String bringUpServiceInnerLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen, boolean enqueueOomAdj) throws TransactionTooLargeException { ... final String procName = r.processName; ... ProcessRecord app;
if (!isolated) { app = mAm.getProcessRecordLocked(procName, r.appInfo.uid); ... if (app != null) { final IApplicationThread thread = app.getThread(); final int pid = app.getPid(); final UidRecord uidRecord = app.getUidRecord(); if (thread != null) { try { ... realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg, enqueueOomAdj); return null; } catch (TransactionTooLargeException e) { throw e; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e); } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } } } else { ... }
if (app == null && !permissionsReviewRequired && !packageFrozen) { if (r.isSdkSandbox) { ... } else { app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated); } ... } ... return null; }
|
注释1处得到ServiceRecord的processName值并赋给procName,其中processName用来描述Service想要在哪个进程中运行,默认是当前进程,我们也可以在AndroidManifest.xml文件中设置android:process属性来新开启一个进程运行Service。
在注释2处将procName和Service的uid传入到AMS的getProcessRecordLocked()方法中,查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来描述运行的应用程序进程的信息。
在注释5处判断Service对应的app为null则说明用来运行Service的应用程序进程不存在,则调用注释6处的AMS的startProcessLocked()方法来创建对应的应用程序进程。
这里只讨论没有设置android:process属性,即应用程序进程存在的情况。在注释3处判断如果用来运行Service的应用程序进程存在,则调用注释4处的realStartServiceLocked()方法来启动Service。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| frameworks/base/services/core/java/com/android/server/am/ActiveServices.java private void realStartServiceLocked(ServiceRecord r, ProcessRecord app, IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg, boolean enqueueOomAdj) throws RemoteException { ... try { ... thread.scheduleCreateService(r, r.serviceInfo, null , app.mState.getReportedProcState()); ... } catch (DeadObjectException e) { ... } finally { ... } ... }
|
在realStartServiceLocked()中调用了thread的scheduleCreateService()方法。其中thread是IApplicationThread类型的,它的实现是ActivityThread的内部类ApplicationThread。
1 2 3 4 5 6 7 8 9 10
| frameworks/base/core/java/android/app/ActivityThread$ApplicationThread 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;
sendMessage(H.CREATE_SERVICE, s); }
|
scheduleCreateService()方法将启动Service的参数封装成CreateServiceData,sendMessage()方法向H类发送类型为CREATE_SERVICE的消息,并将CreateServiceData传递过去。sendMessage()方法有多个重载方法,最终调用的sendMessage()方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| frameworks/base/core/java/android/app/ActivityThread.java private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { ... Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); }
|
这里的mH指的是H,它是ActivityThread的内部类并继承自Handler,是应用程序进程中主线程的消息管理类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| frameworks/base/core/java/android/app/ActivityThread.java class H extends Handler { public void handleMessage(Message msg) { ... switch (msg.what) { ... case CREATE_SERVICE: ... handleCreateService((CreateServiceData)msg.obj); ... break; ... } ... } }
|
handleMessage()方法根据消息类型为CREATE_SERVICE,会调用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 37 38 39 40 41 42 43 44 45 46 47 48
| frameworks/base/core/java/android/app/ActivityThread.java private void handleCreateService(CreateServiceData data) { ... final LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo); Service service = null; try { ... final java.lang.ClassLoader cl; if (data.info.splitName != null) { cl = packageInfo.getSplitClassLoader(data.info.splitName); } else { cl = packageInfo.getClassLoader(); } service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); ContextImpl context = ContextImpl.getImpl(service .createServiceBaseContext(this, packageInfo)); if (data.info.splitName != null) { context = (ContextImpl) context.createContextForSplit(data.info.splitName); } if (data.info.attributionTags != null && data.info.attributionTags.length > 0) { final String attributionTag = data.info.attributionTags[0]; context = (ContextImpl) context.createAttributionContext(attributionTag); } 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()); if (!service.isUiContext()) { VirtualDeviceManager vdm = context.getSystemService(VirtualDeviceManager.class); if (mLastReportedDeviceId == Context.DEVICE_ID_DEFAULT || vdm.isValidVirtualDeviceId(mLastReportedDeviceId)) { service.updateDeviceId(mLastReportedDeviceId); } } service.onCreate(); mServicesData.put(data.token, data); mServices.put(data.token, service); ... } catch (Exception e) { ... } }
|
注释1处获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类;
注释2处获取类加载器;
注释3处根据CreateServiceData对象中存储的Service信息,创建Service实例;
注释4处创建Service的上下文环境ContextImpl对象;
注释5处通过Service的attach()方法来初始化Service;
注释6处调用Service的onCreate()方法,这样Service就启动了;
注释7处将启动的Service加入到ActivityThread的成员变量mServices中,其中mService是ArrayMap类型。