本文出自门心叼龙的博客,属于原创类容,转载请注明出处。
Service的启动流程的还是比较简单的,不像Activity那么复杂,相关联的类和方法都少了很多,不像Activity启动流程里面走着走着就会迷失方向,源码分析这是加强Android内功修炼的必修课,分析了几个流程之后,你就会觉得也不过如此,因为他们的套路都是一样的,大体的实现思想都是相通的,只是具体的代码实现不同罢了。
在上一篇文章我们主要分析了Android10.0 Activity的启动过程,今天我们主要来探索Service的启动过程,本来打算先从5.0开始,然后在分析最新版10.0的启动过程,结果让我失望了,10.0的启动过程和5.0的是方法调用链是一样的,只是有些方法的代码逻辑有些小的改动,它不像Activity的启动流程变化那么大,这说明当时Service启动这块的代码逻辑写的还是非常不错的,Android已经迭代到10了经历了那么版本,这块的代码还是那么的完美稳定,没有什么需要大的改造的地方,10.0中有些小变化会在下面的详解过程会提到,既然5.0和10.0差别不大,索性就以5.0作为研究版本写了这篇文章。
Service是Android四大组件中排行老二,地位仅次于Activity,Activity位于前台向用户展示界面;Service位于后台不可见,但是它承担了大部分的的数据处理工作,主要为其他组件提供后台服务,监控其他组件的运行状态。
Activity中的流程
Service的启动是从Activity的startService方法开始的,这个方法是从他的父类ContextWrapper继承而来的,下面这是Activity的继承关系图:
从上图我们很清晰的看到,Activity继承了ContextThemeWraper,而ContextThemeWraper又继承了ContextWrawper,startService方法正是ContextWraper所提供的,如下所示:
ContextWrapter不但提供了开启服务的startService的方法,而且还提供了停止服务的stopService方法、绑定服务的bindService方法、Activity启动的startActivity方法、广播注册的registerReceiver方法、广播发送的sendBroadcast方法等,Context从英文翻译过来是环境,上下文的意思,它在整个Android操作系统中有着举足轻重的作用,在我们平时的应用开发过程中无处不在的Context,几乎随处可见,因为他是维持各大组件正常工作的核心功能类,它提供了一些系统级别的最基本的操作。
从上面代码的515行,我们看到ContextWraper的startService方法内部调用了mBase的startService方法,mBase的类型是ContextImpl, Activity在创建的时候通过attach方法给mBase变量赋值的,具体代码如下:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//注释1
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
//注释2
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
//注释3
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.voiceInteractor);
if (customIntent != null) {
activity.mIntent = customIntent;c
}
...
ActivityThread的performLaunchActivity方法是不是很熟悉,这是前面文章Activity启动流程中所讲到最重要的一个方法,Activity的创建,Application的创建都是有它来完成的,注释1处通过反射创建了一个activity,注释2处是上下文appContext的创建,注释3 activity调用了attach方法给mBase变量赋值。
注释2处appContext对象是由createBaseContextForActivity创建的,具体代码实现如下:
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
//注释1
ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
appContext.setOuterContext(activity);
Context baseContext = appContext;
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
try {
IActivityContainer container =
ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token);
final int displayId =
container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId();
if (displayId > Display.DEFAULT_DISPLAY) {
Display display = dm.getRealDisplay(displayId, r.token);
baseContext = appContext.createDisplayContext(display);
}
} catch (RemoteException e) {
}
...
return baseContext;
在以上代码的注释1处很清楚的看到 appContext 的类型就是ContextImpl,并且是由它的静态方法 createActivityContext创建的,创建完毕通过activity的attach方法给mBase赋值了。通过这些探索就是为了证实mBase的实现就是ContextImpl,现在我回到之前的启动流程mBase.startServcie(service)这一行,其实就是调用了ContextImpl的startService方法,我们继续看该方法的具体实现:
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess();
//注释1
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
return null;
}
}
ContextImpl中startService方法会调用startServiceCommon方法,而startServiceCommon方法又会在注释1处调用ActivityManagerNative.getDefault()对象来启动一个服务,注意了这块的逻辑在Android10.0中是这式样的:
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
很显然获取服务这块有所变化,在5.0中是由ActivityManagerNative来完成的,在10.0中这个工作交给ActivityManager了,5.0和10.0最主要的变化就在这里,但是他们最终的逻辑都是一样的,最后都走ActivityManagerService的startService方法,此外,其他的逻辑基本没有什么大的改变,我们还是以5.0为研究版本,继续往下走。
在前面的分析Activity启动的时候我们知道ActivityManagerNative.getDefault()对象其实就是ActivityManagerService,此时Service的启动流程直接就走到了ActivityManagerService中,想必很多人还是不很清楚方法的调用流程怎么就过渡到了ActivityManagerService,其实这里用到了Android跨进程通信技术Binder,下面我们看看他的工作原理,搞清楚是怎么由ActivityManagerNative.getDefault()对象的startService方法过渡到ActivityManagerService的startService方法,ActivityManagerNative的getDefault方法的代码实现如下:
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton gDefault = new Singleton() {
//注释1
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
//注释2
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
//注释3
return in;
}
//注释4
return new ActivityManagerProxy(obj);
}
ActivityManagerNative中的getDefault方法很简单只有一行gDefault.get,而gDefault就是Singleton,他是一个单例对象,当调用它的get方法的时候就会执行注释1处onCreate方法,首先通过ServiceManager的getService方法获取了一个Binder,然后在注释2处把这个binder交给了asInterface方法、该方法的主要作用是将服务端binder对象转换为客户端所需要的IActivityManager 接口对象,如果在客户端和服务端在同一进程就会返回本地接口IActivityManager的实现对象,否则就会返回一个ActivityManagerProxy类型的代理对象,很显然该方法最后直接返回的就是一个代理对象ActivityManagerProxy,因为此时需要进行跨进程调用。因此ActivityManagerNative.getDefault()最终获取的是一个代理对象ActivityManagerProxy,紧着会调用这个对象ActivityManagerProxy的startService方法,方法实现如下:
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeInt(userId);
//注释1
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
startService方法会把传递过来的参数进行用Parcel 进行封装,然后在注释1处会调用mRemote的transact方法进行远程方法调用,mRemote对象就是我们前面代码注释4处实例化ActivityManagerProxy对象的时候通过构造方法传递给它的服务端Binder对象。此时客户端会处于挂起状态,ActivityManagerNative的实现类ActivityManagerService的onTransact方法响应,该方法的具体实现如下:
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_SERVICE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
int userId = data.readInt();
//注释1
ComponentName cn = startService(app, service, resolvedType, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
}
onTransact方法响应后会从参数data中解析startService方法所需要的参数,然后在注释1处会调用它的startService方法进行启动服务的操作,至此启动服务的操作由客户端进程切换到了服务端进程,实现了方法的跨进行调用,接下来的我们看ActivityManagerService的startService的方法实现,方法实现如下:
ActivityManagerService的流程
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (DEBUG_SERVICE)
Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//注释1
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
该方法也不长,在最后ActivityManagerService会通过mServices来完成后续的启动操作,mServices的类型是ActiveServices,他是辅助ActivityManagerService进行Service管理的辅助类,包括Service的启动,绑定,停止等。在startService方法的尾部会调用ActiveServices的startServiceLocked方法,该方法的实现如下:
ActiveServices的流程
ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType,
int callingPid, int callingUid, int userId) {
....
ServiceRecord r = res.record;
if (!mAm.getUserManagerLocked().exists(r.userId)) {
Slog.d(TAG, "Trying to start service with non-existent user! " + r.userId);
return null;
}
NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
callingUid, r.packageName, service, service.getFlags(), null, r.userId);
if (unscheduleServiceRestartLocked(r, callingUid, false)) {
if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
}
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
final ServiceMap smap = getServiceMap(r.userId);
boolean addToStarting = false;
...
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
在 ActiveServices的startServiceLocked方法的最后会把后续的启动工作交给startServiceInnerLocked方法来处理,它的代码实现如下所示:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
ServiceRecord r, boolean callerFg, boolean addToStarting) {
ProcessStats.ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
//注释1
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
if (error != null) {
return new ComponentName("!!", error);
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
} else if (DEBUG_DELAYED_STARTS) {
Slog.v(TAG, "Starting background (first=" + first + "): " + r);
}
if (first) {
smap.rescheduleDelayedStarts();
}
} else if (callerFg) {
smap.ensureNotStartingBackground(r);
}
return r.name;
}
在上述代码的注释1处会继续调用bringUpServiceLocked方法,它的源码如下:
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting) {
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;
if (!isolated) {
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) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//注释1
realStartServiceLocked(r, app, execInFg);
return null;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
} else {
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;
}
...
return null;
}
在bringUpServiceLocked方法的注释1处会调用realStartServiceLocked方法,从名字上看来该方法应该会最终完成服务的启动工作,它的具体实现如下:
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
boolean created = false;
try {
String nameTerm;
int lastPeriod = r.shortName.lastIndexOf('.');
nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
if (LOG_SERVICE_START_STOP) {
EventLogTags.writeAmCreateService(
r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
}
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//注释1
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app);
} finally {
if (!created) {
app.services.remove(r);
r.app = null;
scheduleServiceRestartLocked(r, false);
return;
}
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
// If the service is in the started state, and there are no
// pending arguments, then fake up one so its onStartCommand() will
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null));
}
//注释2
sendServiceArgsLocked(r, execInFg, true);
...
}
在realStartServiceLocked方法中首先会调用注释1处app.thread对象的scheduleCreateService方法来完成Servic的创建和onCreate方法的调用,然后在注释2处会调用sendServiceArgsLocked方法完成后续的处理工作,如onStartCommand方法的执行,在分析Activity启动流程的时候我们知道app.thread对象就是ApplicationThread,他是ActivityThread的一个内部类,其本质也是一个Bidner,因此scheduleCreateService方法调用后,启动Service的流程就由服务端进程切换到了客户端进程,接下来我们看ApplicationThread的scheduleCreateService方法实现:
ActivityThread的流程
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);
}
ApplicationThread的scheduleCreateService方法的内部实现很简单,就发送了一个CREATE_SERVICE类型的消息,这个消息会被ActivityThread的mH消息处理器所接收,之后会调用ActivityThread的方法handleCreateService进行处理,该方法的实现如下:
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//注释1
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//注释2
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//注释3
Application app = packageInfo.makeApplication(false, mInstrumentation);
//注释4
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//注释5
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 0, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
在handleCreateService方法中代码还是很精炼的,主要完成了以下几个工作:
- 1.在注释1处通过反射完成了Service的创建
- 2.在注释2处创建了上下文对象Context
- 3.在注释3处创建了Application对象,当然该对象只有一个,如果没有的话会创建,否则就直接返回一个已创建的Application
- 4.在注释4处完成了Service的挂载操作,初始化了一些变量,如context等
- 5.在注释5处完成了Service的onCreate方法的回调
Service的onCreate方法的执行也就意味着Service已经被启动了,启动完成之后还要调用ActiveServcie的sendServiceArgsLocked方法来完成Service的onStartCommand方法的回调,该方法的代码实现如下:
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) {
final int N = r.pendingStarts.size();
if (N == 0) {
return;
}
while (r.pendingStarts.size() > 0) {
try {
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
+ r + " " + r.intent + " args=" + si.intent);
if (si.intent == null && N > 1) {
// If somehow we got a dummy null intent in the middle,
// then skip it. DO NOT skip a null intent when it is
// the only one in the list -- this is to support the
// onStartCommand(null) case.
continue;
}
si.deliveredTime = SystemClock.uptimeMillis();
r.deliveredStarts.add(si);
si.deliveryCount++;
if (si.neededGrants != null) {
mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
si.getUriPermissionsLocked());
}
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app);
}
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
flags |= Service.START_FLAG_REDELIVERY;
}
//注释1
r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
} catch (RemoteException e) {
// Remote process gone... we'll let the normal cleanup take
// care of this.
if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
break;
} catch (Exception e) {
Slog.w(TAG, "Unexpected exception", e);
break;
}
}
}
在注释1处会调用r.app.thread对象的scheduleServiceArgs方法,从此调用流程再次切换到ActivityThrad的内部类对象ApplicationThread的scheduleServiceArgs方法,下面我们看该方法的具体实现:
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
int flags ,Intent args) {
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = taskRemoved;
s.startId = startId;
s.flags = flags;
s.args = args;
sendMessage(H.SERVICE_ARGS, s);
}
其实不用贴代码我们也能猜到必然是发了一个消息,这和Service的onCreate方法的执行是一个套路,ActivityThread的消息处理器收到消息后会调用handleServiceArgs来完成onStartCommand的回调
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) {
//注释1
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 1, data.startId, res);
} catch (RemoteException e) {
// nothing to do.
}
ensureJitEnabled();
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
}
}
}
}
在handleServiceArgs方法的注释1处我们清楚的看到了 s.onStartCommand,这时候Service的onStartCommand方法也被回调了,至此Service的启动流程就全部走完了。
总结
Service的启动流程的还是比较简单的,不像Activity那么复杂,相关联的类和方法都少了很多,不像Activity启动流程里面走着走着就会迷失方向,源码分析这是加强Android内功修炼的必修课,分析了几个流程之后,你就会觉得也不过如此,因为他们的套路都是一样的,大体的实现思想都相通的,只是具体的代码实现不同罢了。最后方便大家对Service启动的理解,我画了一张方法调用时序图,如下:
Activity.startService
ContextWraper.startService
ContextImpl.startService
ContextImpl.startServiceCommon
ActivityManagerService.startService
ActiveService.startServiceLocked
ActiveService.startServiceInnerLocked
ActiveService.bringUpServiceLocked
ActiveService.realStartServiceLocked
ApplicationThread.scheduleCreateService
ActivityThread.handleCreateService
Service.onCreate
ActiveService.sendServiceArgsLocked
ApplicationThread.scheduleServiceArgs
ActivityThread.handleServiceArgs
Service.onStartCommand
问题反馈
在使用学习中有任何问题,请留言,或加入Android、Java开发技术交流群
- QQ群:810970432
- email:[email protected]