Service有两种开启方式即startService、bindService,本章是startService的启动流程。
目录
ContextImpl到AMS的调用过程
时序图
了解
最常见的开启service组件的方式就是在Activity中直接startService,其实在Activity也是Context的一个子类,startService方法定义在Context这个类中。Context相关的集成关系如下图
Context定义了整个应用运行的上下文环境,是一个抽象类,ContextWrapper是其包装类(从名字可以看出装饰者模式的痕迹)真正的实现类是ContextImpl类。
具体过程
activity#startService
public class ContextWrapper extends Context {
@UnsupportedAppUsage
Context mBase;
...
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
}
startService方法中会调用mBase的startService方法,Context类型的mBase对象具体指的是什么呢?这里先卖个关子。通过以下来说明下:
Activity的启动过程中的ActivityThread启动Activity时会创建Activity的上下文环境如下
// ActivityThread 中
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
// 1、首先创建上下文环境
//createBaseContextForActivity 内部通过ContextImpl.createActivityContext 来进行创建
ContextImpl appContext = createBaseContextForActivity(r);
...
// 2、吧上下文环境传与activity关联起来。
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
}
attach 内部将ContextImpl赋值给ContextWrapper 成员变量mBase。由于ContextWrapper 是ContextImpl的装饰者,这样ContextWrapper就可以行驶ContextImpl的功能了。
contextImpl
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
...
//ActivityManager.getService() 返回IActivityManager 对象
//IActivityManager 为AMS的代理类
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
...
}
startServiceCommon方法中会调用AMS的代理IActivityManager的startService方法,最终调用的是AMS的startService方法
ActivityThread 启动Service调用过程
时序图
具体过程
AMS#startService
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
...
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
这里调用mServices的startServiceLocked方法,mServices的类型是ActiveServices 继续往下看
ActiveServices #startServiceLocked
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
...
//1、retrieveServiceLocked方法会查找service参数对应的ServiceRecord,
//并将ServiceRecord封装成serviceLookUpResult返回。
//ps:当找不到ServiceRecord时会调用PMS获取service信息,并封装到ServiceRecord中
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false);
if (res == null) {
return null;
}
if (res.record == null) {
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
// 2、通过上述ServiceLookupResult来取出ServiceRecord 对象
ServiceRecord r = res.record;
...
//3、ServiceRecord 对象继续往下传递
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
ActiveServices #startServiceInnerLocked
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
...
// 调用 bringUpServiceLocked
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
...
return r.name;
}
ActiveServices #bringUpServiceLocked
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
...
//1、processName描述service想要运行的进程,默认值为当前进程
final String procName = r.processName;
String hostingType = "service";
ProcessRecord app;
if (!isolated) {
//2、mAm为AMS类型对象,这里调用AMS的getProcessRecordLocked表示去AMS中查询
//是否存在一个与service对应的ProcessRecord类型对象。
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
if (app != null && app.thread != null) {//3、service应用进程存在
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//4、启动service
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingType = "webview_service";
}
}
// 假如需要的应用进程不存在时,创建应用进程。
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, r.name, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
...
return null;
}
ActiveServices #realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
...
}
app.thread是IApplicationThread 类型,它的实现是ActivityThread的内部类ApplicationThread,所以最终会调用ApplicationThread的scheduleCreateService
ActivityThread类#内部类ApplicationThread#scheduleCreateService
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;
// 内部调用H类的sendMessage方法发送消息。
sendMessage(H.CREATE_SERVICE, s);
}
//sendMessage 重载方法的最终调用
private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
"seq= " + seq);
Message msg = Message.obtain();
msg.what = what;
SomeArgs args = SomeArgs.obtain();
args.arg1 = obj;
args.argi1 = arg1;
args.argi2 = arg2;
args.argi3 = seq;
msg.obj = args;
//H类的sendMessage方法
mH.sendMessage(msg);
}
这里将启动service参数封装成CreateServiceData 对象,并通过H类的sendMessage发送消息。H 类通过handleMessage处理消息。
H#handleMessage
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
...
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
H 类是一个Handle类,是ActivityThread的内部类。这里调用ActivityThread的handleCreateService方法进行后续处理。
ActivityThread#handleCreateService
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
//1、获取要启动Service的应用程序的LoadedApk 信息
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
// 2、获取类加载器,创建service 对象。
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
}
...
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
// 3、创建Service的上下文环境
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
// 4、通过service的attach方法来初始化service
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//5、调用Service 类对象service启动service
service.onCreate();
// 6、和Activity类似,启动的组件信息在ActivityThread类的对应成员信息中存储。
mServices.put(data.token, service);
//mServices是一个ArrayMap
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
The end
参考:
安卓进阶解密:微信读书版