bindService启动流程

作者: 我爱田Hebe | 来源:发表于2022-06-22 21:29 被阅读0次

    本次源码基于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的启动流程:

    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的延迟消息。

    相关文章

      网友评论

        本文标题:bindService启动流程

        本文链接:https://www.haomeiwen.com/subject/gaguvrtx.html