1.前言
AMS(ActivityManagerService)是Android四大组件工作的核心服务类,Activity和Service的启动过程均由其完成。本次基于Android SDK28梳理一下Service的启动流程,加深对Service组件的理解,也有利于更好的定位开发中的问题。
注:由于本次关注的重点是启动流程,因此多余的无关代码没粘贴出来。
2. startService()方式启动Service流程
一般我们调用Context.startService(),最后的实现都是在ContextImpl中的。
2.1 ContextImpl->startService():
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
2.2 startServiceCommon()方法的实现如下:
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
//转调到AMS#startService(),而AMS是运行在system_server进程的,这里是跨进程调用,从应用进程转调到系统进程。
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground, getOpPackageName(),
user.getIdentifier());
}
2.3 系统进程: AMS->startService():
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//mServices是ActiveServices类型的实例,在AMS的构造函数中直接new出来的
//转调到:ActivityServices->startServiceLocked()
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
return res;
}
}
2.4 ActivityServices->startServiceLocked():
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
...
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
...
}
2.5 ActivityServices->startServiceInnerLocked():
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
...
}
2.6 ActivityServices->bringUpServiceLocked():
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
...
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
//转调到realStartServiceLocked继续下一步流程
realStartServiceLocked(r, app, execInFg);
return null;
...
}
}
2.7 ActivityServices->realStartServiceLocked():
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//ipc调用:ApplicationThread->scheduleCreateService
app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
}
2.8 应用进程: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;
//此方法是间接调用了ActivityThread中的handler将消息发送到主线程,交给handleMessage处理
sendMessage(H.CREATE_SERVICE, s);
}
这里要清楚的一个点是,AMS是运行在系统进程的,Service是运行在应用进程的,那就需要一个中介,去完成从AMS在system_server中完成Service的配置项、注册之后,再转回到应用进程,这个就是定义在android.app.ActivityThread.java文件中的ApplicationThread,本质是一个binder接口,他完成了从系统进程转到应用进程的逻辑。
2.9 处理message: ActivityThread.H->handleMessage():
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
2.10 handleCreateService():检查应用进程是否启动,通过反射创建Service实例,调用onCreate()方法
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
Service service = null;
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//通过Service的className,反射创建Service对象
service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//makeApplication():如果Application还未初始化就会反射创建application对象返回
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());
//回调onCreate()
service.onCreate();
//将上面创建的Service实例缓存下来,在进行绑定,解绑,或者回调stop时会直接从缓存中获取
mServices.put(data.token, service);
}
//CreateServiceData数据结构
static final class CreateServiceData {
IBinder token;
ServiceInfo info;
CompatibilityInfo compatInfo;
Intent intent;
...
}
2.11 Service->onCreate():到这一步Service的创建和启动过程完毕,本质上是先反射创建一个Service实例,然后回调onCreate()。但是组件启动都会先检查Application实例是否存在,不存在都会先makeApplication()创建Application实例。
//Service已经完成创建,回调Service的onCreate方法
public void onCreate() {
}