android startService调用流程(一) (android6.0源码)

我们知道要开启一个Service,首先在AndroidManifest.xml注册该Service,然后在Activity中startService
现在我们就看下Service是怎么一步步通过ActivityManagerService启动的。
Context.startService是一个抽象方法,我们知道真正实现Context的类ContextImpl(./frameworks/base/core/java/android/app/ContextImpl.java),于是我们查看其startService代码

  1.     public ComponentName startService(Intent service) {
  2.         warnIfCallingFromSystemProcess();
  3.         return startServiceCommon(service, mUser);
  4.     }
调用了startServiceCommon方法,
  1.     private ComponentName startServiceCommon(Intent service, UserHandle user) {
  2.         try {
  3.             validateServiceIntent(service);
  4.             service.prepareToLeaveProcess();
  5.             ComponentName cn = ActivityManagerNative.getDefault().startService(
  6.                 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
  7.                             getContentResolver()), getOpPackageName(), user.getIdentifier());
  8.             if (cn != null) {
  9.                 if (cn.getPackageName().equals("!")) {
  10.                     throw new SecurityException(
  11.                             "Not allowed to start service " + service
  12.                             + " without permission " + cn.getClassName());
  13.                 } else if (cn.getPackageName().equals("!!")) {
  14.                     throw new SecurityException(
  15.                             "Unable to start service " + service
  16.                             + ": " + cn.getClassName());
  17.                 }
  18.             }
  19.             return cn;
  20.         } catch (RemoteException e) {
  21.             throw new RuntimeException("Failure from system", e);
  22.         }
  23.     }
在第5-7行,通过ActivityManagerProxy代理ActivityManagerService(具体细节参见文章Activity启动过程),调用了ActivityManagerService的startService方法,ActivityManagerService代码如下:

  1.     public ComponentName startService(IApplicationThread caller, Intent service,
  2.             String resolvedType, String callingPackage, int userId)
  3.             throws TransactionTooLargeException {
  4.         enforceNotIsolatedCaller("startService");
  5.         // Refuse possible leaked file descriptors
  6.         if (service != null && service.hasFileDescriptors() == true) {
  7.             throw new IllegalArgumentException("File descriptors passed in Intent");
  8.         }

  9.         if (callingPackage == null) {
  10.             throw new IllegalArgumentException("callingPackage cannot be null");
  11.         }

  12.         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
  13.                 "startService: " + service + " type=" + resolvedType);
  14.         synchronized(this) {
  15.             final int callingPid = Binder.getCallingPid();
  16.             final int callingUid = Binder.getCallingUid();
  17.             final long origId = Binder.clearCallingIdentity();
  18.             ComponentName res = mServices.startServiceLocked(caller, service,
  19.                     resolvedType, callingPid, callingUid, callingPackage, userId);
  20.             Binder.restoreCallingIdentity(origId);
  21.             return res;
  22.         }
  23.     }
经过一些逻辑判断后实际调用了mServices.startServiceLocked。mService定义如下,

  1.     final ActiveServices mServices;
ActiveServices.startServiceLocked代码量约有110行,其中主要是在最后调用了startServiceInnerLocked方法,
接下来我们看下ActiveServices的startServiceInnerLocked方法,代码如下:

  1.     ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
  2.             boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
  3.         ProcessStats.ServiceState stracker = r.getTracker();
  4.         if (stracker != null) {
  5.             stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
  6.         }
  7.         r.callStart = false;
  8.         synchronized (r.stats.getBatteryStats()) {
  9.             r.stats.startRunningLocked();
  10.         }
  11.         String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
  12.         if (error != null) {
  13.             return new ComponentName("!!", error);
  14.         }
  15.       //省略部分代码
  16.     }
其中调用了bringUpServiceLocked方法,bringUpServiceLocked代码量也是110行左右(真特么多啊),但我们可以很清楚的分析到其主要代码如下:

  1.     private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
  2.             boolean whileRestarting) throws TransactionTooLargeException {
  3.         //Slog.i(TAG, "Bring up service:");
  4.         //省略部分代码

  5.         final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
  6.         final String procName = r.processName;
  7.         ProcessRecord app;

  8.         if (!isolated) {
  9.             app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
  10.             if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
  11.                         + " app=" + app);
  12.             if (app != null && app.thread != null) {
  13.                 try {
  14.                     app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
  15.                     realStartServiceLocked(r, app, execInFg);
  16.                     return null;
  17.                 } catch (TransactionTooLargeException e) {
  18.                     throw e;
  19.                 } catch (RemoteException e) {
  20.                     Slog.w(TAG, "Exception when starting service " + r.shortName, e);
  21.                 }

  22.                 // If a dead object exception was thrown -- fall through to
  23.                 // restart the application.
  24.             }
  25.         } else {
  26.             // If this service runs in an isolated process, then each time
  27.             // we call startProcessLocked() we will get a new isolated
  28.             // process, starting another process if we are currently waiting
  29.             // for a previous process to come up.  To deal with this, we store
  30.             // in the service any current isolated process it is running in or
  31.             // waiting to have come up.
  32.             app = r.isolatedProc;
  33.         }
  34.           //省略部分代码
  35.         return null;
  36.     }
在代码的第17行调用到了realStartServiceLocked(是不是很熟悉,和Activity启动过程调用方法名基本一致),
realStartServiceLocked方法代码如下:

  1.     private final void realStartServiceLocked(ServiceRecord r,
  2.             ProcessRecord app, boolean execInFg) throws RemoteException {
  3.         //省略部分代码
  4.         boolean created = false;
  5.         try {
  6.             if (LOG_SERVICE_START_STOP) {
  7.                 String nameTerm;
  8.                 int lastPeriod = r.shortName.lastIndexOf('.');
  9.                 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
  10.                 EventLogTags.writeAmCreateService(
  11.                         r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
  12.             }
  13.             synchronized (r.stats.getBatteryStats()) {
  14.                 r.stats.startLaunchedLocked();
  15.             }
  16.             mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
  17.             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
  18.             app.thread.scheduleCreateService(r, r.serviceInfo,
  19.                     mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
  20.                     app.repProcState);
  21.             r.postNotification();
  22.             created = true;
  23.         } catch (DeadObjectException e) {
  24.             Slog.w(TAG, "Application dead when creating service " + r);
  25.             mAm.appDiedLocked(app);
  26.             throw e;
  27.         } finally {
  28.             if (!created) {
  29.                 // Keep the executeNesting count accurate.
  30.                 final boolean inDestroying = mDestroyingServices.contains(r);
  31.                 serviceDoneExecutingLocked(r, inDestroying, inDestroying);

  32.                 // Cleanup.
  33.                 if (newService) {
  34.                     app.services.remove(r);
  35.                     r.app = null;
  36.                 }

  37.                 // Retry.
  38.                 if (!inDestroying) {
  39.                     scheduleServiceRestartLocked(r, false);
  40.                 }
  41.             }
  42.         }
  43.       //省略部分代码
  44.     }
我们看到在realStartServiceLocked方法的第19-21行调用了app.thread.scheduleCreateService,我们在前面分析Activity启动过程的时候已经知道app.thread变量的类型其实是ActivityThread的私有内部类ApplicationThread,那么我们看下ApplicationThread的scheduleCreateService方法,

  1.         public final void scheduleCreateService(IBinder token,
  2.                 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
  3.             updateProcessState(processState, false);
  4.             CreateServiceData s = new CreateServiceData();
  5.             s.token = token;
  6.             s.info = info;
  7.             s.compatInfo = compatInfo;

  8.             sendMessage(H.CREATE_SERVICE, s);
  9.         }
在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等生命周期方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值