- Android框架层
- Android深入四大组件 categories:
- Android框架层
本文首发于微信公众号「刘望舒」
前言
此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章。
<!--more-->1.ContextImpl到ActivityManageService的调用过程
要启动Service,我们会调用startService方法,它的实现在ContextWrapper中,代码如下所示。 frameworks/base/core/java/android/content/ContextWrapper.java
1public class ContextWrapper extends Context { 2 Context mBase; 3... 4 @Override 5 public ComponentName startService(Intent service) { 6 return mBase.startService(service); 7 } 8... 9}
在startService方法中会调用mBase的startService方法,Context类型的mBase对象具体指的是什么呢?在Android深入四大组件(一)应用程序启动过程(后篇)这篇文章中我们讲过ActivityThread启动Activity时会调用如下代码创建Activity的上下文环境。 frameworks/base/core/java/android/app/ActivityThread.java
1 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2 ... 3 if (activity != null) { 4 Context appContext = createBaseContextForActivity(r, activity);//1 5 ... 6 } 7 activity.attach(appContext, this, getInstrumentation(), r.token, 8 r.ident, app, r.intent, r.activityInfo, title, r.parent, 9 r.embeddedID, r.lastNonConfigurationInstances, config, 10 r.referrer, r.voiceInteractor, window); 11 ... 12 } 13 return activity; 14}
在注释1处创建上下文对象appContext ,并传入Activity的attach方法中,将Activity与上下文对象appContext 关联起来,这个上下文对象appContext 的具体类型是什么,我们接着查看createBaseContextForActivity方法,代码如下所示。 frameworks/base/core/java/android/app/ActivityThread.java
1private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) { 2... 3 4 ContextImpl appContext = ContextImpl.createActivityContext( 5 this, r.packageInfo, r.token, displayId, r.overrideConfig); 6 appContext.setOuterContext(activity); 7 Context baseContext = appContext; 8 ... 9 return baseContext; 10}
这里可以得出结论,上下文对象appContext 的具体类型就是ContextImpl 。Activity的attach方法中将ContextImpl赋值给ContextWrapper的成员变量mBase中,因此,mBase具体指向就是ContextImpl 。 那么,我们紧接着来查看ContextImpl的startService方法,代码如下所示。 frameworks/base/core/java/android/app/ContextImpl.java
1@Override 2public ComponentName startService(Intent service) { 3 warnIfCallingFromSystemProcess(); 4 return startServiceCommon(service, mUser); 5} 6 private ComponentName startServiceCommon(Intent service, UserHandle user) { 7 try { 8 validateServiceIntent(service); 9 service.prepareToLeaveProcess(this); 10 /** 11 * 1 12 */ 13 ComponentName cn = ActivityManagerNative.getDefault().startService( 14 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( 15 getContentResolver()), getOpPackageName(), user.getIdentifier()); 16 ... 17 return cn; 18 } catch (RemoteException e) { 19 throw e.rethrowFromSystemServer(); 20 } 21 }
startService方法中会return startServiceCommon方法,在startServiceCommon方法中会在注释1处调用ActivityManageService(AMS)的代理对象ActivityManagerProxy(AMP)的startService方法,最终会调用AMS的startService方法。至于注释1处的代码为何会调用AMS的startService方法,在Android深入四大组件(一)应用程序启动过程(前篇)这篇文章中已经讲过,这里不再赘述。 ContextImpl到ActivityManageService的调用过程如下面的时序图所示。

2.ActivityThread启动Service
我们接着来查看AMS的startService方法。 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
1Override 2public ComponentName startService(IApplicationThread caller, Intent service, 3 String resolvedType, String callingPackage, int userId) 4 throws TransactionTooLargeException { 5 ... 6 synchronized(this) { 7 ... 8 ComponentName res = mServices.startServiceLocked(caller, service, 9 resolvedType, callingPid, callingUid, callingPackage, userId);//1 10 Binder.restoreCallingIdentity(origId); 11 return res; 12 } 13}
注释1处调用mServices的startServiceLocked方法,mServices的类型是ActiveServices,ActiveServices的startServiceLocked方法代码如下所示。 frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
1ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, 2 int callingPid, int callingUid, String callingPackage, final int userId) 3 throws TransactionTooLargeException { 4 ... 5 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting); 6 } 7 8 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, 9 boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { 10 11 ... 12 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); 13 ... 14 return r.name; 15 }
startServiceLocked方法的末尾return了startServiceInnerLocked方法,而startServiceInnerLocked方法中又调用了bringUpServiceLocked方法: frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
1 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, 2 boolean whileRestarting, boolean permissionsReviewRequired) 3 throws TransactionTooLargeException { 4... 5 final String procName = r.processName;//1 6 ProcessRecord app; 7 if (!isolated) { 8 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);//2 9 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid 10 + " app=" + app); 11 if (app != null && app.thread != null) {//3 12 try { 13 app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, 14 mAm.mProcessStats); 15 realStartServiceLocked(r, app, execInFg);//4 16 return null; 17 } catch (TransactionTooLargeException e) { 18 throw e; 19 } catch (RemoteException e) { 20 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 21 } 22 } 23 } else { 24 app = r.isolatedProc; 25 } 26 27 if (app == null && !permissionsReviewRequired) {//5 28 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, 29 "service", r.name, false, isolated, false)) == null) {//6 30 ... 31 } 32 if (isolated) { 33 r.isolatedProc = app; 34 } 35 } 36 37 ... 38}
在注释1处得到ServiceRecord的processName的值赋值给procName ,其中processName用来描述Service想要在哪个进程运行,默认是当前进程,我们也可以在AndroidManifes配置文件中设置android:process属性来新开启一个进程运行Service。注释2处将procName和Service的uid传入到AMS的getProcessRecordLocked方法中,来查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来记录运行的应用程序进程的信息。注释5处需要判断两个条件,一个是用来运行Service的应用程序进程不存在,另一个是应用程序之间的组件调用不需要检查权限,满足这两个条件则调用注释6处的AMS的startProcessLocked方法来创建对应的应用程序进程。关于创建应用程序进程请查看Android应用程序进程启动过程(前篇) 和Android应用程序进程启动过程(后篇)这两篇文章。注释3处判断如果用来运行Service的应用程序进程存在,则调用注释4处的realStartServiceLocked方法:
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
1private final void realStartServiceLocked(ServiceRecord r, 2 ProcessRecord app, boolean execInFg) throws RemoteException { 3 ... 4 try { 5 ... 6 app.thread.scheduleCreateService(r, r.serviceInfo, 7 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), 8 app.repProcState); 9 r.postNotification(); 10 created = true; 11 } catch (DeadObjectException e) { 12 ... 13 } 14 ... 15}
在realStartServiceLocked方法中调用了app.thread的scheduleCreateService方法。其中app.thread是IApplicationThread类型的,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。ApplicationThread的scheduleCreateService方法如下所示。 frameworks/base/core/java/android/app/ActivityThread.java
1 public final void scheduleCreateService(IBinder token, 2 ServiceInfo info, CompatibilityInfo compatInfo, int processState) { 3 updateProcessState(processState, false); 4 CreateServiceData s = new CreateServiceData(); 5 s.token = token; 6 s.info = info; 7 s.compatInfo = compatInfo; 8 sendMessage(H.CREATE_SERVICE, s); 9 }
首先将要启动的信息封装成CreateServiceData 对象并传给sendMessage方法,sendMessage方法向H发送CREATE_SERVICE消息,H是ActivityThread的内部类并继承Handler。这个过程和应用程序的启动过程(根Activity启动过程)是类似的。我们接着查看H的handleMessage方法。 frameworks/base/core/java/android/app/ActivityThread.java
1 public void handleMessage(Message msg) { 2 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 3 switch (msg.what) { 4 ... 5 case CREATE_SERVICE: 6 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, 7 ("serviceCreate: " + String.valueOf(msg.obj))); 8 handleCreateService((CreateServiceData)msg.obj); 9 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 10 break; 11 ... 12 } 13 ... 14 } 15 ... 16 }
handleMessage方法根据消息类型,调用了handleCreateService方法:
frameworks/base/core/java/android/app/ActivityThread.java
1 private void handleCreateService(CreateServiceData data) { 2 unscheduleGcIdler(); 3 LoadedApk packageInfo = getPackageInfoNoCheck( 4 data.info.applicationInfo, data.compatInfo);//1 5 Service service = null; 6 try { 7 java.lang.ClassLoader cl = packageInfo.getClassLoader();//2 8 service = (Service) cl.loadClass(data.info.name).newInstance();//3 9 } catch (Exception e) { 10 ... 11 } 12 } 13 try { 14 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 15 16 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);//4 17 context.setOuterContext(service); 18 19 Application app = packageInfo.makeApplication(false, mInstrumentation); 20 service.attach(context, this, data.info.name, data.token, app, 21 ActivityManagerNative.getDefault());//5 22 service.onCreate();//6 23 mServices.put(data.token, service);//7 24 ... 25 } catch (Exception e) { 26 ... 27 } 28 }
注释1处获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类。注释2处通过调用LoadedApk的getClassLoader方法来获取类加载器。接着在注释3处根据CreateServiceData对象中存储的Service信息,将Service加载到内存中。注释4处创建Service的上下文环境ContextImpl对象。注释5处通过Service的attach方法来初始化Service。注释6处调用Service的onCreate方法,这样Service就启动了。在注释7处将启动的Service加入到ActivityThread的成员变量mServices中,其中mServices是ArrayMap类型。
最后给出这一节的时序图。

