Service分为两种工作状态,启动状态和绑定状态,通过调用startService()可进入启动状态,通过bindService()可进入绑定状态,本篇文章主要讲解startService()启动Service的过程。(额,android的版本还是26)
我们平时通过startService()启动一个Service的时候,最终都是调用的ContextWrapper的startService(),我们来看下这个方法
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
上述方法中调用了mBase对象的startService()方法,mBase的类型是Context,Context的实现类是ContextImpl,我们来看下ContextImpl的startService()方法
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
......
//调用了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()方法中,调用了startServiceCommon()方法,在startServiceCommon()中,通过ActivityManager.getService()获取到ActivityManagerService的对象,然后调用了ActivityManagerService的startService()方法
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
......
synchronized(this) {
......
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
在上述方法中,通过mServices对象调用了startServiceLocked()方法,mServices是ActiveServices类的对象,可以看做是辅助ActivityManagerServices来管理Service的类,我们来看下它的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);
return cmp;
}
在该方法的最后,调用了startServiceInnerLocked()方法
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting)
throws TransactionTooLargeException {
......
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
......
return r.name;
}
调用了bringUpServiceLocked()方法,该方法也是启动Service过程中比较重要的一个方法
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,boolean whileRestarting, boolean permissionsReviewR