startService启动流程

本次源码基于Android11分析

相关源码:

/frameworks/base/core/java/android/content/ContextWrapper.java
/frameworks/base/core/java/android/app/ContextImpl.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
/frameworks/base/core/java/android/app/ActivityThread.java

启动Service有两种方式,一种是 startService,一种是bindService。其中startService和bindService会分别执行不同的方法。如startService会执行onStartCommand方法,而bindService会执行onBind、onUnbind方法。

其中startService的启动方式是不能进行通信的,而且其Service的生命周期不跟调用方同步。binderService启动方式则可以通过Binder进行通信。一下是startService的流程图:

1. startService发起进程端

1.1 ContextWrapper.startService

public class ContextWrapper extends Context {

  Context mBase;

  @Override
  public ComponentName startService(Intent service) {
      // mBase的实例是ContextImpl
      return mBase.startService(service);
  }
}

1.2 ContextImpl.startService

class ContextImpl extends Context {
  @Override
  public ComponentName startService(Intent service) {
      // 检测是否为system_server进程
      warnIfCallingFromSystemProcess();
      return startServiceCommon(service, false, mUser);
  }

  private ComponentName startServiceCommon(Intent service, boolean requireForeground,
                                           UserHandle user) {
      try {
          //检测Intent的包名是否为空,throw异常
          validateServiceIntent(service);
          service.prepareToLeaveProcess(this);


          // ActivityManager.getService()通过ServiceManager得到AMS的BinderProxy,
          // 并调用AMS的BinderProxy其startService方法。
          ComponentName cn = ActivityManager.getService().startService(
                  mMainThread.getApplicationThread(), service,
                  service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                  getOpPackageName(), getAttributionTag(), user.getIdentifier());



          // 对返回的ComponentName进行检查,异常抛throw
          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());
              } else if (cn.getPackageName().equals("?")) {
                  throw new IllegalStateException(
                          "Not allowed to start service " + service + ": " + cn.getClassName());
              }
          }
          return cn;
      } catch (RemoteException e) {
          throw e.rethrowFromSystemServer();
      }
  }
}
// 获取ASM的BinderProxy
public class ActivityManager {
  @UnsupportedAppUsage
  public static IActivityManager getService() {
      return IActivityManagerSingleton.get();
  }

  @UnsupportedAppUsage
  private static final Singleton IActivityManagerSingleton =
          new Singleton() {
              @Override
              protected IActivityManager create() {
                  // Context.ACTIVITY_SERVICE是activity
                  final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                  final IActivityManager am = IActivityManager.Stub.asInterface(b);
                  return am;
              }
          };
}

startServiceCommon方法先检查Intent,然后通过Binder通信调用AMS.startService方法,其中参数mMainThread.getApplicationThread()是一个Binder,AMS通过其和调用端进行通信,其过程如下所示:

2. system_server进程

在startService的过程中ActivityManagerServer的作用大致是找到对应的Servive并调用其生命周期。

2.1 AMS.startService

public class ActivityManagerService extends IActivityManager.Stub
      implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

  final ActiveServices mServices;

  @Override
  public ComponentName startService(IApplicationThread caller, Intent service,
                                    String resolvedType, boolean requireForeground, String callingPackage,
                                    String callingFeatureId, int userId)
          throws TransactionTooLargeException {
      //当调用者是孤立进程,则抛出异常
      enforceNotIsolatedCaller("startService");
      // 拒绝可能泄露的文件描述符
      if (service != null && service.hasFileDescriptors() == true) {
          throw new IllegalArgumentException("File descriptors passed in Intent");
      }
      if (callingPackage == null) {
          throw new IllegalArgumentException("callingPackage cannot be null");
      }

      synchronized (this) {
          final int callingPid = Binder.getCallingPid(); //调用者pid
          final int callingUid = Binder.getCallingUid(); //调用者uid
          final long origId = Binder.clearCallingIdentity();
          ComponentName res;
          try {

              // 调用ActiveServices.startServiceLocked方法
              res = mServices.startServiceLocked(caller, service,
                      resolvedType, callingPid, callingUid,
                      requireForeground, callingPackage, callingFeatureId, userId);

          } finally {
              Binder.restoreCallingIdentity(origId);
          }
          return res;
      }
  }

AMS.startService方法作了一下调用端进程的检查后,直接调用ActiveServices.startServiceLocked方法,并把参数全部传递给ActiveServices类。

2.2 ActiveServices.startServiceLocked

public final class ActiveServices {

  ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
                                   int callingPid, int callingUid, boolean fgRequired, String callingPackage,
                                   @Nullable String callingFeatureId, final int userId)
          throws TransactionTooLargeException {
      //  继续调用startServiceLocked方法
      return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
              callingPackage, callingFeatureId, userId, false);
  }

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
                                   int callingPid, int callingUid, boolean fgRequired, String callingPackage,
                                   @Nullable String callingFeatureId, final int userId,
                                   boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {

      // 检查是否为前台进程
      final boolean callerFg;
      // .....
   
      //根据Intent检索对应的服务信息
      ServiceLookupResult res =
              retrieveServiceLocked(service, null, resolvedType, callingPackage,
                      callingPid, callingUid, userId, true, callerFg, false, false);
     
      //对于非前台进程的调度
      if (!callerFg && !fgRequired && r.app == null
              && mAm.mUserController.hasStartedUserState(r.userId)) {
          // 获取启动Service的所在进程信息 ProcessRecord
          ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
      }

       
          // ...
          // 调用startServiceInnerLocked
          ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);

          return cmp;
      }
  }

ActiveServices.startServiceLocked方法会获取调用端的ProcessRecord,和获取被调用端的ServiceRecord、ProcessRecord查看此次启动的Service是否要加入延迟队列。最终调用startServiceInnerLocked方法继续执行逻辑。

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
                                        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
      //。。。
      // 调用bringUpServiceLocked方法
      String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
      //。。。
      return r.name;
  }
  
  private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
                                      boolean whileRestarting, boolean permissionsReviewRequired)
          throws TransactionTooLargeException {
      if (r.app != null && r.app.thread != null) {
          // 如果service已经启动,那么多次启动Service时会多次调用service.onStartCommand()方法
          sendServiceArgsLocked(r, execInFg, false);
          return null;
      }

      final boolean isolated = (r.serviceInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
      final String procName = r.processName;
      ProcessRecord app;
      if (!isolated) {
          //根据进程名和uid,查询ProcessRecord
          app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
          if (app != null && app.thread != null) {
              // 目标进程已存在
              try {
                  app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                  // 启动服务,调用Service对应方法
                  realStartServiceLocked(r, app, execInFg);
                  return null;
              } catch (TransactionTooLargeException e) {
                  throw e;
              } catch (RemoteException e) {
                  Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
              }

          }
      } else {
          app = r.isolatedProc;
      }

     //... 对Service进程的做一些空判断和延迟操作
      return null;
  }

获取Service所对应的进程,如果进程创建成功而且不延迟启动,则调用realStartServiceLocked方法调用Service的一些方法。

2.3 ActiveServices.realStartServiceLocked

  private final void realStartServiceLocked(ServiceRecord r,
                                            ProcessRecord app, boolean execInFg) throws RemoteException {
   
      // handle发送延迟消息,如果在规定时间还没有被取消,则证明方法执行时间长,则抛ANR异常。
      bumpServiceExecutingLocked(r, execInFg, "create");
      //...
      try {
          //调用Service对应onCreate()方法
          app.thread.scheduleCreateService(r, r.serviceInfo,
                  mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                  app.getReportedProcState());
   
      } catch (DeadObjectException e) {
          mAm.appDiedLocked(app, "Died when creating service");
          throw e;
      } finally {
         //...
      }

      //服务 进入onStartCommand()
      sendServiceArgsLocked(r, execInFg, true);

      // 
      if (r.delayedStop) {
          r.delayedStop = false;
          if (r.startRequested) {
              //停止服务
              stopServiceLocked(r);
          }
      }
  }

// 通过Handler发送延迟时间,到时间内没被取消则抛ANR异常
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
      long now = SystemClock.uptimeMillis();
      if (r.executeNesting == 0) {
          //...
          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) {
              // 发送Handler
              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;
      //当超时后仍没有remove该SERVICE_TIMEOUT_MSG消息,则执行service Timeout流程
      mAm.mHandler.sendMessageDelayed(msg,
              proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
  }

 // 执行Service的onStartCommand方法
 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
                                           boolean oomAdjusted) throws TransactionTooLargeException {
      while (r.pendingStarts.size() > 0) {
          //...
          // 装弹,延迟发送一条消息,如果执行onStartCommand方法超过
          bumpServiceExecutingLocked(r, execInFg, "start");
          //...
          try {
              // 调用AT.scheduleServiceArgs,最终调用onStartCommand
              r.app.thread.scheduleServiceArgs(r, slice);
          }
      }

  }

realStartServiceLocked方法,分别会调用app.thread所对应的scheduleCreateService、scheduleServiceArgs,此app.thread是Service所在进程的ApplicationThread类。在调用方法前,还会调用bumpServiceExecutingLocked方法发送一个延迟消息,如果这个消息没被取消,则会弹ANR。

3. Service进程

3.1 ApplicationThread.scheduleCreateService

  private class ApplicationThread extends IApplicationThread.Stub {

      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;
          // 通过Handler发送消息执行
          sendMessage(H.CREATE_SERVICE, s);
      }

  }

  public void handleMessage(Message msg) {
      switch (msg.what) {
          case CREATE_SERVICE:
              handleCreateService((CreateServiceData) msg.obj);
              break;
      }
  }

  // 创建对应的Service并执行onCreate()方法
  private void handleCreateService(CreateServiceData data) {
      //当应用处于后台即将进行GC,而此时被调回到活动状态,则跳过本次gc
      unscheduleGcIdler();
      // 获取LoadedApk
      LoadedApk packageInfo = getPackageInfoNoCheck(
              data.info.applicationInfo, data.compatInfo);

      Service service = null;
      try {
          // 根据LoadedApk创建ContextImpl
          ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
          //创建Application对象
          Application app = packageInfo.makeApplication(false, mInstrumentation);
          // 获取ClassLoader
          java.lang.ClassLoader cl = packageInfo.getClassLoader();
          // 通过反射创建Service对象
          service = packageInfo.getAppFactory()
                  .instantiateService(cl, data.info.name, data.intent);
          context.getResources().addLoaders(
                  app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

          context.setOuterContext(service);
          // 调用service.attach绑定资源文件
          service.attach(context, this, data.info.name, data.token, app,
                  ActivityManager.getService());
          // 调用 service.onCreate()方法
          service.onCreate();
          mServices.put(data.token, service);
          try {
              // onCreate()执行完成,拆弹过程,最终调用到ActiveServices.serviceDoneExecutingLocked方法
              ActivityManager.getService().serviceDoneExecuting(
                      data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
          } catch (RemoteException e) {
              throw e.rethrowFromSystemServer();
          }
      } catch (Exception e) {
        //...
      }
  }

先会创建一个ContextImpl对象,在通过反射创建Service对象,通过调用Service.attach方法将资源传给Service对象,最后调用Service.onCreate对象,并向AMS发送取消延迟发送消息。

3.2 ApplicationThread. scheduleServiceArgs

  private class ApplicationThread extends IApplicationThread.Stub {

      public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
          List 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);
          }
      }
  }

  public void handleMessage(Message msg) {
      switch (msg.what) {
          case SERVICE_ARGS:
              handleServiceArgs((ServiceArgsData) msg.obj);
              break;
      }
  }

  // 创建对应的Service并执行onCreate()方法
  private void handleServiceArgs(ServiceArgsData data) {
      Service s = mServices.get(data.token);
      if (s != null) {
          try {
              // 调用Service的onStartCommand方法
              int res;
              if (!data.taskRemoved) {
                  res = s.onStartCommand(data.args, data.flags, data.startId);
              }

              try {
                  // 向AMS取消Handler发送ANR消息
                  ActivityManager.getService().serviceDoneExecuting(
                          data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
              } catch (RemoteException e) {
                  throw e.rethrowFromSystemServer();
              }
          }
      }
  }

根据缓存找到对应的Service,并执行Service. onStartCommand()方法,并向AMS发送了取消ANR的延迟消息。

在来看看stopService会发生什么:

 private void handleStopService(IBinder token) {
      Service s = mServices.remove(token);
      if (s != null) {
          try {
              s.onDestroy();
              s.detachAndCleanUp();
              Context context = s.getBaseContext();
              if (context instanceof ContextImpl) {
                  final String who = s.getClassName();
                  ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
              }

              QueuedWork.waitToFinish();

              try {
                  ActivityManager.getService().serviceDoneExecuting(
                          token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
              } catch (RemoteException e) {
                  throw e.rethrowFromSystemServer();
              }
              
          }
      }

执行Service.onDestroy方法,并对Service和对应ContextImpl进行clear操作。startService启动的Service的生命周期并不会跟调用端同步,所以要自己手动调用停止操作:stopSelf()或stopService()

你可能感兴趣的:(startService启动流程)