bindService启动流程

本次源码基于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
复制代码

通过bindService启动的Service,会执行Service的onCreate、onBind、onUnbind、onDestroy方法,可以通过onBind方法返回的Binder对象和调用端进行通信,并且Service的生命周期和调用端同步。 如下是启动bindService的代码

var stu: Student? = null
val connection = object : ServiceConnection {
  override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
      stu = Student.Stub.asInterface(p1)
  }
  override fun onServiceDisconnected(p0: ComponentName?) {
  }
}
val intent = Intent(this, Student::class.java)
bindService(intent, connection, BIND_AUTO_CREATE)

复制代码

如下是bindService的启动流程:

image.png

1.bindService 发起端进程

1.1 ContextWrapper.bindService

public class ContextWrapper extends Context {

  public boolean bindService(Intent service, ServiceConnection conn,
                             int flags) {
      //mBase为ContentImpl
      return mBase.bindService(service, conn, flags);
  }
}
复制代码

继续调用ContentImpl.bindService方法:

class ContextImpl extends Context {
  
  public boolean bindService(Intent service, ServiceConnection conn, int flags) {
      warnIfCallingFromSystemProcess();
      return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
              getUser());
  }

 final @NonNull LoadedApk mPackageInfo;
  private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
                                    String instanceName, Handler handler, Executor executor, UserHandle user) {
      // 将ServiceConnection转换成Binder对象变量,用于进程间通信
      IServiceConnection sd;
      //...
      if (mPackageInfo != null) {
          // 将ServiceConnection转换成可跨进程
          if (executor != null) {
              sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
          } else {
              sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
          }
      } else {
          throw new RuntimeException("Not supported in system context");
      }
      validateServiceIntent(service);
      try {
          //...
          // 调用AMS.bindIsolatedService方法
          int res = ActivityManager.getService().bindIsolatedService(
                  mMainThread.getApplicationThread(), getActivityToken(), service,
                  service.resolveTypeIfNeeded(getContentResolver()),
                  sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
          if (res < 0) {
              throw new SecurityException(
                      "Not allowed to bind to service " + service);
          }
          return res != 0;
      } catch (RemoteException e) {
          throw e.rethrowFromSystemServer();
      }
  }
}
复制代码

首先将ServiceConnection变量存储到可跨进程通信的Binder对象并赋值到sd变量,并把sd变量传给AMS中,后续AMS通过这个Binder通信。最后调用AMS.bindIsolatedService跨进程调用方法。在分析另一个AMS进程前,先分析本进程如何

public final class LoadedApk {

  @UnsupportedAppUsage
  public final IServiceConnection getServiceDispatcher(ServiceConnection c,
                                                       Context context, Handler handler, int flags) {
      return getServiceDispatcherCommon(c, context, handler, null, flags);
  }

  private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
                                                        Context context, Handler handler, Executor executor, int flags) {
      synchronized (mServices) {
          LoadedApk.ServiceDispatcher sd = null;
          //...
          // 创建ServiceDispatcher对象,并把ServiceConnection参数作为其变量之一
          sd = new ServiceDispatcher(c, context, executor, flags);
          //...
          // 返回ServiceDispatcher.InnerConnection内部类,其继承IServiceConnection.Stub,是个binder
          return sd.getIServiceConnection();
      }
  }
}

static final class ServiceDispatcher {
  // 返回的是此对象
  private final ServiceDispatcher.InnerConnection mIServiceConnection;
  // 存储ServiceConnection的变量
  private final ServiceConnection mConnection;
  private final Context mContext;
  private final Handler mActivityThread;
  private final Executor mActivityExecutor;
  private final ServiceConnectionLeaked mLocation;

  ServiceDispatcher(ServiceConnection conn,
                    Context context, Handler activityThread, int flags) {
      //创建InnerConnection对象,等会会返回该对象
      mIServiceConnection = new InnerConnection(this);
      //用户定义的ServiceConnection
      mConnection = conn;
      mContext = context;
      mActivityThread = activityThread;
      mActivityExecutor = null;
      mLocation = new ServiceConnectionLeaked(null);
      mLocation.fillInStackTrace();
      mFlags = flags;
  }

  // 返回的是mIServiceConnection变量,是Binder类
  IServiceConnection getIServiceConnection() {
      return mIServiceConnection;
  }

  //内部的Binder类
  private static class InnerConnection extends IServiceConnection.Stub {

      final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

      // 通过构造函数弱引用ServiceDispatcher对象,此对象有ServiceConnection变量
      InnerConnection(LoadedApk.ServiceDispatcher sd) {
          mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
      }

      // 调用ServiceDispatcher.connected()方法
      public void connected(ComponentName name, IBinder service, boolean dead)
              throws RemoteException {
          LoadedApk.ServiceDispatcher sd = mDispatcher.get();
          if (sd != null) {
              sd.connected(name, service, dead);
          }
      }
  }

  // ServiceDispatcher.connected()的方法
  public void connected(ComponentName name, IBinder service, boolean dead) {
      if (mActivityExecutor != null) {
          // 在线程池执行一个任务
          mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
      } else if (mActivityThread != null) {
          // 给主线程发送一个post一个任务
          mActivityThread.post(new RunConnection(name, service, 0, dead));
      } else {
          // 如果上述两个都为空,则执行doConnected方法
          doConnected(name, service, dead);
      }
  }

  private final class RunConnection implements Runnable {

      RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
          mName = name;
          mService = service;
          mCommand = command;
          mDead = dead;
      }

      public void run() {
          if (mCommand == 0) {
              // mCommand为0 ,进入doConnected方法
              doConnected(mName, mService, mDead);
          } else if (mCommand == 1) {
              doDeath(mName, mService);
          }
      }

      final ComponentName mName;
      final IBinder mService;
      final int mCommand;
      final boolean mDead;
  }

  // 调用ServiceConnection.onServiceConnected()方法
  public void doConnected(ComponentName name, IBinder service, boolean dead) {
      ServiceDispatcher.ConnectionInfo old;
      ServiceDispatcher.ConnectionInfo info;

      synchronized (this) {
          if (mForgotten) {
              return;
          }
          old = mActiveConnections.get(name);
          if (old != null && old.binder == service) {
              return;
          }

          if (service != null) {
              info = new ConnectionInfo();
              info.binder = service;
              //创建死亡监听对象
              info.deathMonitor = new DeathMonitor(name, service);
              try {
                  //建立死亡通知
                  service.linkToDeath(info.deathMonitor, 0);
                  mActiveConnections.put(name, info);
              } catch (RemoteException e) {
                  mActiveConnections.remove(name);
                  return;
              }

          } else {
              mActiveConnections.remove(name);
          }

          if (old != null) {
              old.binder.unlinkToDeath(old.deathMonitor, 0);
          }
      }

      // 如果有旧服务,它现在已断开连接。
      if (old != null) {
          mConnection.onServiceDisconnected(name);
      }
      if (dead) {
          mConnection.onBindingDied(name);
      }
      //如果有新的可行服务,它现在已连接。
      if (service != null) {
          // 回调用户定义的ServiceConnection()
          mConnection.onServiceConnected(name, service);
      } else {
          // The binding machinery worked, but the remote returned null from onBind().
          mConnection.onNullBinding(name);
      }
  }

}
复制代码

创建LoadedApk.ServiceDispatcher类的实例化对象,对象里面包含了一个Binder对象LoadedApk.ServiceDispatcher.InnerConnection,方法最后就是返回这个Binder对象。AMS也通过这个Binder对象通信调用ServiceConnection.onServiceConnected()方法。

AMS处理bindService请求

首先调用AMS的bindIsolatedService方法

public class ActivityManagerService extends IActivityManager.Stub {

  final ActiveServices mServices;

  public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
                                 String resolvedType, IServiceConnection connection, int flags, String instanceName,
                                 String callingPackage, int userId) throws TransactionTooLargeException {
      // 空判断 ...
      // 调用ActiveServices.bindServiceLocked方法
      synchronized (this) {
          return mServices.bindServiceLocked(caller, token, service,
                  resolvedType, connection, flags, instanceName, callingPackage, userId);
      }
  }
}
复制代码

AMS方法首先进行空判断,然后调用ActiveServices类的bindServiceLocked()方法:

public final class ActiveServices {

  int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
                        String resolvedType, final IServiceConnection connection, int flags,
                        String instanceName, String callingPackage, final int userId)
          throws TransactionTooLargeException {

      final int callingPid = Binder.getCallingPid();
      final int callingUid = Binder.getCallingUid();
      //查询发起端所对应的进程记录结构
      final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
      if (callerApp == null) {
          throw new SecurityException(
                  "Unable to find app for caller " + caller
                          + " (pid=" + callingPid
                          + ") when binding service " + service);
      }

      ActivityServiceConnectionsHolder<ConnectionRecord> activity = null;
      //token不为空, 代表着发起方具有activity上下文
      if (token != null) {
          activity = mAm.mAtmInternal.getServiceConnectionsHolder(token);
          if (activity == null) {
              return 0;
          }
      }

      int clientLabel = 0;
      PendingIntent clientIntent = null;
      final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;

      ...
      //根据发送端所在进程的SchedGroup来决定是否为前台service
      final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;

      // 1. 根据传递进来Intent来检索相对应的服务,service变量就是Intent
      ServiceLookupResult res =
              retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
                      callingPid, callingUid, userId, true,
                      callerFg, isBindExternal, allowInstant);
      // 空检查
      if (res == null) {
          return 0;
      }
      if (res.record == null) {
          return -1;
      }

      //2. 查询到相应的Service记录
      ServiceRecord s = res.record;

      final long origId = Binder.clearCallingIdentity();
      try {

          // 调用ServiceRecord.retrieveAppBindingLocked方法
          AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
          //创建对象ConnectionRecord,此处connection来自发起方
          ConnectionRecord c = new ConnectionRecord(b, activity,
                  connection, flags, clientLabel, clientIntent,
                  callerApp.uid, callerApp.processName, callingPackage);

          IBinder binder = connection.asBinder();
          ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
          if (clist == null) {
              clist = new ArrayList<>();
              mServiceConnections.put(binder, clist);
          }
          clist.add(c); // clist是ServiceRecord.connections的成员变量

          if ((flags & Context.BIND_AUTO_CREATE) != 0) {
              //更新当前service活动时间
              s.lastActivity = SystemClock.uptimeMillis();
              //3. 启动service,这个过程跟startService过程一致
              if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                      permissionsReviewRequired) != null) {
                  return 0;
              }
          }
        //.....
      return 1;
  }
复制代码

bindServiceLocked方法主要做了三件事:

  1. 调用retrieveServiceLocked方法,根据Intent解析寻找要启动的Service,并得到ServiceLookupResult对象实例。
  2. 根据ServiceLookupResult对象实例得到ServiceRecord对象。
  3. 调用bringUpServiceLocked方法,开始启动Service。

1. retrieveServiceLocked根据Intent解析要启动的ServiceRecord

  private ServiceLookupResult retrieveServiceLocked(Intent service,
                                                    String instanceName, String resolvedType, String callingPackage,
                                                    int callingPid, int callingUid, int userId,
                                                    boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
                                                    boolean allowInstant) {
      ServiceRecord r = null;

      userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId,
              /* allowAll= */false, getAllowMode(service, callingPackage),
              /* name= */ "service", callingPackage);

      ServiceMap smap = getServiceMapLocked(userId);
      // 1. 根据Intent获取全类名
      final ComponentName comp;
      if (instanceName == null) {
          comp = service.getComponent();
      } else {
          final ComponentName realComp = service.getComponent();
          if (realComp == null) {
              throw new IllegalArgumentException("Can't use custom instance name '" + instanceName
                      + "' without expicit component in Intent");
          }
          comp = new ComponentName(realComp.getPackageName(),
                  realComp.getClassName() + ":" + instanceName);
      }

      // 2. 根据全类名在缓存中查找相应的ServiceRecord
      if (comp != null) {
          r = smap.mServicesByInstanceName.get(comp);
      }

      // ServiceRecord为空
      if (r == null) {
          try {
              // 3. 通过PKMS来查询相应的ResolveInfo
              ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service,
                      resolvedType, flags, userId, callingUid);
              ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
              if (sInfo == null) {
                  return null;
              }
              //获取组件名
              ComponentName className = new ComponentName(
                      sInfo.applicationInfo.packageName, sInfo.name);
              if (userId > 0) {
                  //服务是否属于单例模式
                  if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                          sInfo.name, sInfo.flags)
                          && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                      userId = 0;
                      smap = getServiceMapLocked(0);
                  }
                  sInfo = new ServiceInfo(sInfo);
                  sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
              }
              r = smap.mServicesByInstanceName.get(name);
              if (r == null && createIfNeeded) {
                  final Intent.FilterComparison filter
                          = new Intent.FilterComparison(service.cloneFilter());
                  //创建Restarter对象
                  final ServiceRestarter res = new ServiceRestarter();
                  final BatteryStatsImpl.Uid.Pkg.Serv ss;
                  final BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
                  synchronized (stats) {
                      ss = stats.getServiceStatsLocked(
                              sInfo.applicationInfo.uid, name.getPackageName(),
                              name.getClassName());
                  }
                  
                  // 3.2 创建ServiceRecord对象
                  r = new ServiceRecord(mAm, ss, className, name, definingPackageName,
                          definingUid, filter, sInfo, callingFromFg, res);
                  r.mRecentCallingPackage = callingPackage;
                  res.setService(r);
                  smap.mServicesByInstanceName.put(name, r);
                  smap.mServicesByIntent.put(filter, r);

                  //确保该组件不再位于pending队列
                  for (int i = mPendingServices.size() - 1; i >= 0; i--) {
                      final ServiceRecord pr = mPendingServices.get(i);
                      if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                              && pr.instanceName.equals(name)) {
                          mPendingServices.remove(i);
                      }
                  }
              }
          } catch (RemoteException ex) {
              //运行在同一个进程,不会发生RemoteException
          }
      }
      if (r != null) {
          //各种权限检查,不满足条件则返回为null的service
          //...
          //4. 创建Service查询结果对象
          return new ServiceLookupResult(r, null);
      }
      return null;
  }

复制代码

retrieveServiceLocked方法主要做了四件事:

  1. 根据Intent数据获取Service的全类名
  2. 根据全类名在缓存查找是否有ServiceRecord
  3. 如果缓存中没有ServiceRecord,则根据PKMS查找对应的ResolveInfo,并创建一个ServiceRecord对象
  4. 最后如果ServiceRecord对象不为空,则根据ServiceRecord创建一个ServiceLookupResult对象实例并返回。

2. bringUpServiceLocked启动Service

  // 启动Service的方法
  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;
      }

      if (!whileRestarting && mRestartingServices.contains(r)) {
          return null; //等待延迟重启的过程,则直接返回
      }

      // 启动service前,把service从重启服务队列中移除
      if (mRestartingServices.remove(r)) {
          clearRestartingIfNeededLocked(r);
      }

      // service正在启动,将delayed设置为false
      if (r.delayed) {
          getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
          r.delayed = false;
      }

      //确保拥有该服务的user已经启动,否则停止;
      if (!mAm.mUserController.hasStartedUserState(r.userId)) {
          String msg = "Unable to launch app "
                  + r.appInfo.packageName + "/"
                  + r.appInfo.uid + " for service "
                  + r.intent.getIntent() + ": user " + r.userId + " is stopped";
          bringDownServiceLocked(r);
          return msg;
      }

      //服务正在启动,设置package停止状态为false
      try {
          AppGlobals.getPackageManager().setPackageStoppedState(
                  r.packageName, false, r.userId);
      } catch (RemoteException e) {
      } catch (IllegalArgumentException e) {
          Slog.w(TAG, "Failed trying to unstop package "
                  + r.packageName + ": " + e);
      }

      final boolean isolated = (r.serviceInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
      final String procName = r.processName;
      ProcessRecord app;
      if (!isolated) {
          // 1. 根据进程名和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);
                  // 2. 调用realStartServiceLocked方法启动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;
      }

      // 对于进程没有启动的情况
      if (app == null && !permissionsReviewRequired) {
          // 3. 通过AMS启动service所要运行的进程
          if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                  hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {
              String msg = "Unable to launch app "
                      + r.appInfo.packageName + "/"
                      + r.appInfo.uid + " for service "
                      + r.intent.getIntent() + ": process is bad";
              // 进程启动失败
              bringDownServiceLocked(r);
              return msg;
          }
          if (isolated) {
              r.isolatedProc = app;
          }
      }

      if (!mPendingServices.contains(r)) {
          mPendingServices.add(r);
      }

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

      return null;
  }

复制代码

bringUpServiceLocked方法主要做了两件事:

  1. 检查进程是否启动,如果启动了,则调用realStartServiceLocked方法开始真正启动Service。
  2. 如果进程没启动,则先创建进程,进程创建完成后才调用realStartServiceLocked方法开始真正启动Service。

继续查看realStartServiceLocked方法

// 真是启动Service方法
  private final void realStartServiceLocked(ServiceRecord r,
                                            ProcessRecord app, boolean execInFg) throws RemoteException {
      if (app.thread == null) {
          throw new RemoteException();
      }
      //...
      // 1. 发送delay消息,若onCreate方法超时执行未取消,则引发ANR
      bumpServiceExecutingLocked(r, execInFg, "create");
      try {
          //...
          // 2. 通过ApplicationThread调用Service.onCreate方法
          app.thread.scheduleCreateService(r, r.serviceInfo,
                  mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                  app.getReportedProcState());
          r.postNotification();
          created = true;
      } catch (DeadObjectException e) {
          mAm.appDiedLocked(app, "Died when creating service");
          throw e;
      } finally {
          //...
      }

      // 3. 检查是否需要执行onBind()方法
      requestServiceBindingsLocked(r, execInFg);
      //...
      //4. 服务 进入onStartCommand()
      sendServiceArgsLocked(r, execInFg, true);
      //...
  }

复制代码

realStartServiceLocked方法主要做了四件事:

  1. 调用bumpServiceExecutingLocked()方法发送一个延迟消息,为Service的onCreate执行时间装弹。
  2. 调用app.thread.scheduleCreateService()方法,通过Service所在进程的ApplicationThread类,去创建Service并调用Service的onCreate()方法。
  3. 调用requestServiceBindingsLocked()方法,检查是否需要执行Service的onBind()方法。
  4. 调用sendServiceArgsLocked()方法,检查是否需要执行Service的onStartCommand()方法
bumpServiceExecutingLocked延迟发送ANR消息:
  static final int SERVICE_TIMEOUT = 20 * 1000;

  static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;

  // 发送一个延迟消息,消息没被取消,则执行ANR。fg参数为是否为前台Service
  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流程
      // 在前台延迟20s,否则延迟200s
      mAm.mHandler.sendMessageDelayed(msg,
              proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
  }

复制代码

如果是前台Service则延迟20s发送ANR消息,如果是后台Service则延迟200s发送ANR消息。

requestServiceBindingsLocked检查是否需要执行onBind()方法:
  private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
          throws TransactionTooLargeException {
      // 通过bindService的启动方式,bindings一定不为空
      for (int i = r.bindings.size() - 1; i >= 0; i--) {
          IntentBindRecord ibr = r.bindings.valueAt(i);
          if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
              break;
          }
      }
  }

  private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
                                                    boolean execInFg, boolean rebind) throws TransactionTooLargeException {
      if (r.app == null || r.app.thread == null) {
          // If service is not currently running, can't yet bind.
          return false;
      }
      if ((!i.requested || rebind) && i.apps.size() > 0) {
          try {
              // 1. ANR装炸弹
              bumpServiceExecutingLocked(r, execInFg, "bind");
              r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
              // 2. 通过ApplicationThread调用Service的onBind()方法
              r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                      r.app.getReportedProcState());
              if (!rebind) {
                  i.requested = true;
              }
              i.hasBound = true;
              i.doRebind = false;
          }
          //...
      }
      return true;
  }
复制代码

如果ServiceRecord.bindings大小>0,则调用requestServiceBindingLocked方法,先通过bumpServiceExecutingLocked方法给onBind()方法发送延迟的ANR消息,然后调用 r.app.thread.scheduleBindService()方法通过ApplicationThread类调用Service的onBind()方法。

sendServiceArgsLocked检查是否需要执行onStartCommand方法

  private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
                                           boolean oomAdjusted) throws TransactionTooLargeException {
      final int N = r.pendingStarts.size();
      if (N == 0) {
          return;
      }

      ArrayList<ServiceStartArgs> args = new ArrayList<>();

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

  }
复制代码

如果ServiceRecord.pendingStarts大小>0则通过r.app.thread.scheduleServiceArgs调用Service的onStartCommand方法。

ActivityThread创建并执行Service

由于bindService启动的Service并不会执行onStartCommand()方法,所以这里只分析onCreate()、onBind()方法:

执行onCreate()

AMS通过调用app.thread.scheduleCreateService()方法去调用Service的onCreate()方法的执行。

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();
      // 1.1 获取LoadedApk
      LoadedApk packageInfo = getPackageInfoNoCheck(
              data.info.applicationInfo, data.compatInfo);

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

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

通过Handler通信,最终会调用ActivityThread. handleCreateService方法,该方法主要6件事:

  1. 通过getPackageInfoNoCheck方法创建一个LoadedApk实例对象。并通过LoadedApk对象创建一个ContextImpl对象。
  2. 调用packageInfo.makeApplication创建一个Application对象
  3. 通过反射创建对应的Service实例对象
  4. 调用service.attach方法绑定资源文件
  5. 调用service.onCreate()方法
  6. 调用ActivityManager.getService().serviceDoneExecuting向AMS取消延迟发送的ANR消息。

执行onBind()

AMS通过调用r.app.thread.scheduleBindService()方法去执行Service的onBind()方法。

public final class ActivityThread extends ClientTransactionHandler {

  private class ApplicationThread extends IApplicationThread.Stub {

      public final void scheduleBindService(IBinder token, Intent intent,
                                            boolean rebind, int processState) {
          updateProcessState(processState, false);
          BindServiceData s = new BindServiceData();
          s.token = token;
          s.intent = intent;
          s.rebind = rebind;

          sendMessage(H.BIND_SERVICE, s);
      }

  }

  public void handleMessage(Message msg) {
      switch (msg.what) {
          case BIND_SERVICE:
              handleBindService((BindServiceData) msg.obj);
              break;
      }
  }


  private void handleBindService(BindServiceData data) {
      Service s = mServices.get(data.token);
      if (s != null) {
          try {

              try {
                  if (!data.rebind) {
                      // 1. 执行Service.onBind()回调方法
                      IBinder binder = s.onBind(data.intent);
                      // 2. 将onBind返回值传递回给AMS,
                      // 让其回调ServiceConnection方法,并取消ANR消息
                      ActivityManager.getService().publishService(
                              data.token, data.intent, binder);
                  } else {
                      // 取消ANR消息
                      ActivityManager.getService().serviceDoneExecuting(
                              data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                  }
              }
              //...
          }
      }

  }
复制代码

通过Handler通信最终调用到ActivityThread. handleBindService方法,该方法主要做两件事:

  1. 调用Service.onBind()方法
  2. 调用ActivityManager.getService().publishService通过AMS向发起方的ServiceConnection进行回调,并取消ANR的延迟消息。
  public class ActivityManagerService extends IActivityManager.Stub
          implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

      final ActiveServices mServices;

      public void publishService(IBinder token, Intent intent, IBinder service) {
          // Refuse possible leaked file descriptors
          if (intent != null && intent.hasFileDescriptors() == true) {
              throw new IllegalArgumentException("File descriptors passed in Intent");
          }

          synchronized (this) {
              if (!(token instanceof ServiceRecord)) {
                  throw new IllegalArgumentException("Invalid service token");
              }
              mServices.publishServiceLocked((ServiceRecord) token, intent, service);
          }
      }
  }

  public final class ActiveServices {

      void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
          final long origId = Binder.clearCallingIdentity();
          try {
              if (r != null) {
                  Intent.FilterComparison filter
                          = new Intent.FilterComparison(intent);
                  IntentBindRecord b = r.bindings.get(filter);
                  if (b != null && !b.received) {
                      b.binder = service;
                      b.requested = true;
                      b.received = true;
                      ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
                      for (int conni = connections.size() - 1; conni >= 0; conni--) {
                          ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                          for (int i = 0; i < clist.size(); i++) {
                              ConnectionRecord c = clist.get(i);
                              try {
                                  //1. 调用发起方进程的LoadedApk.ServiceDispatcher.InnerConnection.connected方法
                                  c.conn.connected(r.name, service, false);
                              } catch (Exception e) {
                              }
                          }
                      }
                  }
                  // 2. 取消ANR消息
                  serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
              }
          } finally {
              Binder.restoreCallingIdentity(origId);
          }
      }
  }

复制代码

最终调用到ActiveServices.publishServiceLocked()方法,向发起方的进行回调,并取消的ANR的延迟消息。

总结:

bingService会执行的方法有 onCreate、onBind、onUnBind、onDestory,其中onBind()方法会返回一个Binder对象。

  • 发起方在调用bingService时要传入一个ServiceConnection实例对象,并把这个对象封装在一个Binder对象中,便于AMS回调。
  • AMS则通过Intent找到对应的Service记录,如果Service的进程没启动则先创建进程,进程启动后依此通过进程的ActivityThread创建并调用Service的onCreate、onBind方法,并在调用方法前发送一个延迟的ANR消息
  • Service进程的ActivityThread在onCreate()时先通过反射创建Service,并调用Service的attach、onCreate方法。在onBind()时先调用Service的onBinder方法,并向AMS发送i个给发起方的ServiceConnection的回调。在执行完方法后发送一个取消执行ANR的延迟消息。

猜你喜欢

转载自juejin.im/post/7109749890082668580