先来一张不专业的时序图
基于源码9.0
比如我们在Activity中要启动Service,我们要调用Context的startService方法,这是一个抽象方法,ContextWrapper类继承了Context类实现了startService方法。
public abstract ComponentName startService(Intent service);
ContextWrapper的startService方法。
@Override
public ComponentName startService(Intent service) {
//调用mBase的startService方法
return mBase.startService(service);
}
方法内部调用了mBase的startService方法。mBase的声明类型是Context,运行时类型是一个ContextImpl对象。可以参考从点击桌面应用图标到MainActivity的onResume过程分析文章。
ContextImpl的startService方法
@Override
public ComponentName startService(Intent service) {
//...
//调用startServiceCommon方法
return startServiceCommon(service, false, mUser);
}
ContextImpl的startServiceCommon方法。
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
//调用ActivityManagerService的startService方法
ComponentName cn = ActivityManager.getService().startService(mMainThread.getApplicationThread(),
service, service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
//...
return cn;
} catch(RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
ContextImpl的startService方法内部调用了ActivityManagerService的startService方法来启动Service。
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 {
//注释1. 调用ActiveServices的startServiceLocked方法
res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
在注释1处,调用了 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 {
//...
//注释2
ServiceLookupResult res =retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
//...
//注释3
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
在注释2处,调用retrieveServiceLocked来查找是否有目标service对应的ServiceRecord,查找时先在本地的ServiceMap中查询,如果没有找到,就会调用PackageManagerService去获取目标service对应的信息,并封装到ServiceRecord中,最后将ServiceRecord封装为ServiceLookupResult返回。
继续往下走注释3处,调用了ActiveServices的startServiceInnerLocked方法
ActiveServices的startServiceInnerLocked方法
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg,
boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
//...
//注释4,调用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 {
//...
ProcessRecord app;
if(!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
//注释4,如果要启动的Service所在的进程存在
if(app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
mAm.mProcessStats);
//注释5,调用realStartServiceLocked方法
realStartServiceLocked(r, app, execInFg);
return null;
} catch(TransactionTooLargeException e) {
throw e;
} catch(RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
}
//...
//注释6,如果要启动的Service所在的进程不存在,先启动进程
if(app == null && !permissionsReviewRequired) {
//注释7
if((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, r.name, false, isolated, false)) == null) {
//...
}
//...
}
//...
}
在注释4处,如果要启动的Service所在的进程存在,那么直接调用realStartServiceLocked方法启动目标service。如果要启动的Service所在的进程不存在,那么在注释7处先调用ActivityManagerService的startProcessLocked启动进程。这里我们暂时只看启动的Service所在的进程存在的情况。
ActiveServices的realStartServiceLocked方法
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//...
//注释8-1处,调用 bumpServiceExecutingLocked 方法,内部会通过一个异步线程的Handler来延迟发送一个消息,用来检测Service的生命周期方法是否执行超时了。
bumpServiceExecutingLocked(r, execInFg, "create");
//注释8处,调用ApplicationThread的scheduleCreateService方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
//...
//注释9,
sendServiceArgsLocked(r, execInFg, true);
}
在realStartServiceLocked方法中,注释8-1处,调用 bumpServiceExecutingLocked 方法,内部会通过一个异步线程的Handler来延迟发送一个消息,用来检测Service的生命周期方法是否执行超时了。
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg,
String why) {
if(DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING " + why + " of " +
r + " in app " + r.app);
else if(DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
">>> EXECUTING " + why + " of " + r.shortName);
PHASE_THIRD_PARTY_APPS_CAN_START too,
boolean timeoutNeeded = true;
long now = SystemClock.uptimeMillis();
if(r.executeNesting == 0) {
r.executeFg = fg;
ServiceState stracker = r.getTracker();
if(stracker != null) {
stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(),
now);
}
if(r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if(timeoutNeeded && r.app.executingServices.size() == 1) {
scheduleServiceTimeoutLocked(r.app);
}
}
} else if(r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
if(timeoutNeeded) {
//注释1处,调用 scheduleServiceTimeoutLocked方法。
scheduleServiceTimeoutLocked(r.app);
}
}
r.executeFg |= fg;
r.executeNesting++;
r.executingStart = now;
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if(proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
//前台服务20秒,后台服务200秒超时。
mAm.mHandler.sendMessageDelayed(msg, proc.execServicesFg ?
SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
如果onCreate方法在20秒内还没有执行完成,最终会执行ActiveServices的 serviceTimeout 方法。就会弹出ANR弹窗。
void serviceTimeout(ProcessRecord proc) {
//...
if(anrMessage != null) {
//调用 AppErrors的 appNotResponding 方法。
mAm.mAppErrors.appNotResponding(proc, null, null, false, anrMessage);
}
}
AppErrors 会发送一个 SHOW_NOT_RESPONDING_UI_MSG 消息, ActivityManagerService 收到后,会执行 AppErrors 的 handleShowAnrUi方法。弹出ANR弹窗。
void handleShowAnrUi(Message msg) {
Dialog dialogToShow = null;
synchronized(mService) {
AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg
.obj;
final ProcessRecord proc = data.proc;
if(proc == null) {
Slog.e(TAG, "handleShowAnrUi: proc is null");
return;
}
if(proc.anrDialog != null) {
Slog.e(TAG, "App already has anr dialog: " + proc);
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
AppNotRespondingDialog.ALREADY_SHOWING);
return;
}
Intent intent = new Intent("android.intent.action.ANR");
if(!mService.mProcessesReady) {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
Intent.FLAG_RECEIVER_FOREGROUND);
}
mService.broadcastIntentLocked(null, null, intent, null, null,
0, null, null, null, AppOpsManager.OP_NONE, null, false,
false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */
);
boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
if(mService.canShowErrorDialogs() || showBackground) {
dialogToShow = new AppNotRespondingDialog(mService,
mContext, data);
proc.anrDialog = dialogToShow;
} else {
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
AppNotRespondingDialog.CANT_SHOW);
// Just kill the app if there is no dialog to be shown.
mService.killAppAtUsersRequest(proc, null);
}
}
// If we've created a crash dialog, show it without the lock held
if(dialogToShow != null) {
dialogToShow.show();
}
}
有点扯远了。。。回到ActiveServices的realStartServiceLocked方法的注释8处,调用ApplicationThread的scheduleCreateService方法。
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;
sendMessage(H.CREATE_SERVICE, s);
}
scheduleCreateService方法最终还是调用了mH.sendMessage(msg)
来发送消息,这个过程就是handler发送消息和处理消息的过程,不再详细叙述,我们直接看mH的handleMessage方法即可。(这里插一句,ApplicationThread是ActivityThread的内部类,mH是ActivityThread的一个成员变量)
public void handleMessage(Message msg) {
switch(msg.what) {
case CREATE_SERVICE:
handleCreateService((CreateServiceData) msg.obj);
break;
}
}
handleMessage方法内部调用了ActivityThread的handleCreateService方法
ActivityThread的handleCreateService方法
private void handleCreateService(CreateServiceData data) {
//...
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo,
data.compatInfo);
Service service = null;
try {
//构建Service对象
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory().instantiateService(cl, data.info
.name, data.intent);
} catch(Exception e) {
//...
}
try {
//创建service的上下文环境
ContextImpl context = ContextImpl.createAppContext(this,
packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false,
mInstrumentation);
//service初始化
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用service的onCreate方法
service.onCreate();
mServices.put(data.token, service);
try {
//注释1处
ActivityManager.getService().serviceDoneExecuting(data.token,
SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch(RemoteException e) {
throw e.rethrowFromSystemServer();
}
//...
}
}
在这个方法中创建了service的实例,创建service的上下文环境,调用service的attach方法来初始化service。并调用了service的onCreate方法了,到这里service已经启动了,那么Service的onStartCommond方法是在哪里调用的呢?在探究之前我们注意一下上面方法的注释1处。
try {
//注释1处
ActivityManager.getService().serviceDoneExecuting(data.token,
SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch(RemoteException e) {
throw e.rethrowFromSystemServer();
}
调用 ActivityManagerService 的 serviceDoneExecuting 方法,内部会调用 ActiveServices 的 serviceDoneExecutingLocked 方法。 移除掉超时检测的message。
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
if(r != null) {
//...
final long origId = Binder.clearCallingIdentity();
//调用 serviceDoneExecutingLocked 方法。
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Binder.restoreCallingIdentity(origId);
}
}
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
boolean finishing) {
//...
r.executeNesting--;
if(r.executeNesting <= 0) {
if(r.app != null) {
r.app.execServicesFg = false;
r.app.executingServices.remove(r);
if(r.app.executingServices.size() == 0) {
//移除超时检测的message。
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG,
r.app);
} else if(r.executeFg) {
// Need to re-evaluate whether the app still needs to be in the foreground.
for(int i = r.app.executingServices.size() - 1; i >= 0; i--) {
if(r.app.executingServices.valueAt(i).executeFg) {
r.app.execServicesFg = true;
break;
}
}
}
}
r.executeFg = false;
//...
}
}
让我们回到ActiveServices的realStartServiceLocked方法中的注释9处,这里内部最终会调用Service的onStartCommand方法。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//...
//注释8处,调用ApplicationThread的scheduleCreateService方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
//...
//注释9处
sendServiceArgsLocked(r, execInFg, true);
}
在调用完ApplicationThread的scheduleCreateService方法以后,在注释9处调用了sendServiceArgsLocked方法。
ActiveServices的sendServiceArgsLocked方法
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
//...
//注释10处,
bumpServiceExecutingLocked(r, execInFg, "start");
//注释11处,调用ApplicationThread的scheduleServiceArgs方法
r.app.thread.scheduleServiceArgs(r, slice);
//...
}
在注释11处,调用了ApplicationThread的scheduleServiceArgs方法
ApplicationThread的scheduleServiceArgs方法
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);
}
}
该方法内部也是调用mH.sendMessage(msg)
来发送消息,接下来直接看mH的handleMessage方法即可。
public void handleMessage(Message msg) {
switch(msg.what) {
case SERVICE_ARGS:
//调用ActivityThread的handleServiceArgs方法
handleServiceArgs((ServiceArgsData) msg.obj);
break;
}
}
ActivityThread的handleServiceArgs方法
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if(s != null) {
try {
if(data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
}
int res;
if(!data.taskRemoved) {
//调用Service的onStartCommand方法
res = s.onStartCommand(data.args, data.flags, data.startId);
}
try {
ActivityManager.getService().serviceDoneExecuting(data.token,
SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch(RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
在这里调用了Service的onStartCommand方法。
结尾:整篇文章看下来感觉需要叙述的地方不多,直接一路看代码就行了,哈哈。
参考
- 《Android进阶解密》
- startService的Service启动过程分析
- Android深入四大组件(二)Service的启动过程