之前写过App和Activity的启动流程分析:
现在梳理下Service的启动流程吧
基于Android 10的源码分析
ContextWrapper.startService()
Context的实现是ContextImpl
,因此到ContextImpl
中查看:
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
// 关键, 利用ActivityManagerService启动Service
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
还是调用的ActivityManagerService
去执行的.
ActivityManagerService.startService()
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
// 这里的mServices是ActiveServices
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
然后就到了ActiveServices
中,这个类其实在之前的启动流程分析文章中也有提到过:
// startService 和bindService两种方式其实最终都会走到这里
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
r.setProcess(app);
boolean created = false;
try {
//ApplicationThread,关键点
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
if (newService && created) {
app.addBoundClientUidsOfNewService(r);
}
// 这里也很关键
sendServiceArgsLocked(r, execInFg, true);
}
这期间调用链其实很长,这里直接走到最后一步.
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;
// handler机制
sendMessage(H.CREATE_SERVICE, s);
}
Handler收到消息之后:
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
加载Service类,并执行onCreate回调
private void handleCreateService(CreateServiceData data) {
// 获取APP信息
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
// 使用ClassLoader加载并实例化Service类
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
try {
// 创建Context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
// 创建Application
Application app = packageInfo.makeApplication(false, mInstrumentation);
// 执行service的attach方法
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
///调用service的onCreate回调
service.onCreate();
mServices.put(data.token, service);
try {
// 通知AMS服务
// SERVICE_DONE_EXECUTING_ANON表示异步执行
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
可以看到,Service的启动过程其实和Activity的启动过程大同小异,都是使用ClassLoader加载的.
还有最后一句,通知ActivityManagerService,看下这部分干了什么:
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
synchronized(this) {
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
// SERVICE_DONE_EXECUTING_ANON,0,0
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
final long origId = Binder.clearCallingIdentity();
//主要是一些超时逻辑
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Binder.restoreCallingIdentity(origId);
}
可以看到这一步其实没什么.
现在回到onCreate回调之后的处理逻辑:
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
ArrayList<ServiceStartArgs> args = new ArrayList<>();
// 关键点
r.app.thread.scheduleServiceArgs(r, slice);
}
这个会执行到ActivityThread的ApplicationThread中:
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++) {
ServiceStartArgs ssa = list.get(i);
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = ssa.taskRemoved;
s.startId = ssa.startId;
s.flags = ssa.flags;
s.args = ssa.args;
// 关键
sendMessage(H.SERVICE_ARGS, s);
}
}
Handelr收到消息之后有:
case SERVICE_ARGS:
handleServiceArgs((ServiceArgsData)msg.obj);
break;
这里其实会执行Service 的onStartCommand()回调:
Service.onStartCommand()
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
int res;
if (!data.taskRemoved) {
// 调用Service的onStartCommand方法
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
// 通知AMS service启动
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
执行完Service的onStartCommand()方法之后,会通知AMS:
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
if (r != null) {
if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
// 执行这个分支
r.callStart = true;
switch (res) {
case Service.START_STICKY_COMPATIBILITY:
case Service.START_STICKY: {
// We are done with the associated start arguments.
r.findDeliveredStart(startId, false, true);
// Don't stop if killed.
r.stopIfKilled = false;
break;
}
case Service.START_NOT_STICKY: {
// We are done with the associated start arguments.
r.findDeliveredStart(startId, false, true);
if (r.getLastStartId() == startId) {
// There is no more work, and this service
// doesn't want to hang around if killed.
r.stopIfKilled = true;
}
break;
}
case Service.START_REDELIVER_INTENT: {
// We'll keep this item until they explicitly
// call stop for it, but keep track of the fact
// that it was delivered.
ServiceRecord.StartItem si = r.findDeliveredStart(startId, false, false);
if (si != null) {
si.deliveryCount = 0;
si.doneExecutingCount++;
// Don't stop if killed.
r.stopIfKilled = true;
}
break;
}
case Service.START_TASK_REMOVED_COMPLETE: {
// Special processing for onTaskRemoved(). Don't
// impact normal onStartCommand() processing.
r.findDeliveredStart(startId, true, true);
break;
}
default:
throw new IllegalArgumentException(
"Unknown service start result: " + res);
}
if (res == Service.START_STICKY_COMPATIBILITY) {
r.callStart = false;
}
}
}
}
这里其实就是处理不同类型的Service,比如Sticky Service的启动逻辑,这里不仔细说了.
总结
- Service的启动流程和Activity的启动流程大同小异
- ActivityThread和AMS起到了关键性的作用
- 不同类型Service在AMS中有处理逻辑