我们知道要开启一个Service,首先在AndroidManifest.xml注册该Service,然后在Activity中startService
现在我们就看下Service是怎么一步步通过ActivityManagerService启动的。
Context.startService是一个抽象方法,我们知道真正实现Context的类ContextImpl(./frameworks/base/core/java/android/app/ContextImpl.java),于是我们查看其startService代码
- public ComponentName startService(Intent service) {
- warnIfCallingFromSystemProcess();
- return startServiceCommon(service, mUser);
- }
调用了startServiceCommon方法,
- private ComponentName startServiceCommon(Intent service, UserHandle user) {
- try {
- validateServiceIntent(service);
- service.prepareToLeaveProcess();
- ComponentName cn = ActivityManagerNative.getDefault().startService(
- mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
- getContentResolver()), getOpPackageName(), 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) {
- throw new RuntimeException("Failure from system", e);
- }
- }
在第5-7行,通过ActivityManagerProxy代理ActivityManagerService(具体细节参见文章Activity启动过程),调用了ActivityManagerService的startService方法,ActivityManagerService代码如下:
- public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, String callingPackage, int userId)
- throws TransactionTooLargeException {
- enforceNotIsolatedCaller("startService");
- // Refuse possible leaked file descriptors
- if (service != null && service.hasFileDescriptors() == true) {
- throw new IllegalArgumentException("File descriptors passed in Intent");
- }
- if (callingPackage == null) {
- throw new IllegalArgumentException("callingPackage cannot be null");
- }
- if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
- "startService: " + service + " type=" + resolvedType);
- synchronized(this) {
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
- final long origId = Binder.clearCallingIdentity();
- ComponentName res = mServices.startServiceLocked(caller, service,
- resolvedType, callingPid, callingUid, callingPackage, userId);
- Binder.restoreCallingIdentity(origId);
- return res;
- }
- }
经过一些逻辑判断后实际调用了mServices.startServiceLocked。mService定义如下,
- final ActiveServices mServices;
ActiveServices.startServiceLocked代码量约有110行,其中主要是在最后调用了startServiceInnerLocked方法,
接下来我们看下ActiveServices的startServiceInnerLocked方法,代码如下:
- ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
- boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
- 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();
- }
- String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
- if (error != null) {
- return new ComponentName("!!", error);
- }
- //省略部分代码
- }
其中调用了bringUpServiceLocked方法,bringUpServiceLocked代码量也是110行左右(真特么多啊),但我们可以很清楚的分析到其主要代码如下:
- private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
- boolean whileRestarting) throws TransactionTooLargeException {
- //Slog.i(TAG, "Bring up service:");
- //省略部分代码
- 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);
- realStartServiceLocked(r, app, execInFg);
- return null;
- } catch (TransactionTooLargeException e) {
- throw e;
- } 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;
- }
在代码的第17行调用到了realStartServiceLocked(是不是很熟悉,和Activity启动过程调用方法名基本一致),
realStartServiceLocked方法代码如下:
- private final void realStartServiceLocked(ServiceRecord r,
- ProcessRecord app, boolean execInFg) throws RemoteException {
- //省略部分代码
- boolean created = false;
- try {
- if (LOG_SERVICE_START_STOP) {
- String nameTerm;
- int lastPeriod = r.shortName.lastIndexOf('.');
- nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
- 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);
- 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);
- throw e;
- } finally {
- if (!created) {
- // Keep the executeNesting count accurate.
- final boolean inDestroying = mDestroyingServices.contains(r);
- serviceDoneExecutingLocked(r, inDestroying, inDestroying);
- // Cleanup.
- if (newService) {
- app.services.remove(r);
- r.app = null;
- }
- // Retry.
- if (!inDestroying) {
- scheduleServiceRestartLocked(r, false);
- }
- }
- }
- //省略部分代码
- }
我们看到在realStartServiceLocked方法的第19-21行调用了app.thread.scheduleCreateService,我们在前面分析Activity启动过程的时候已经知道app.thread变量的类型其实是ActivityThread的私有内部类ApplicationThread,那么我们看下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方法的最后一句sendMessage发送了一个CREATE_SERVICE的消息,那么这里service启动流程我们分析了一半了,接收CREATE_SERVICE消息并如何处理我们放到第二部分,接下来总结一下这一部分分析的Service启动流程。
首先Context.startService实际调用的是ContextImpl.startService方法,从这里开始,
ContextImpl.startService -> startServiceCommon -> ActivityManagerService.startService -> ActiveServices.startServiceLocked -> startServiceInnerLocked -> bringUpServiceLocked ->
realStartServiceLocked -> ApplicationThread.scheduleCreateService -> sendMessage.
最终通过ActivityThread的mh变量(Handler类型)发送了一个CREATE_SERVICE的消息,第二部分会将mh如何处理该消息并回调Service的onCreate等生命周期方法。