理解Android进程启动之全过程

yatd1288 7年前
   <h2><strong>一. 概述</strong></h2>    <p>Android系统将进程做得很友好的封装,对于上层app开发者来说进程几乎是透明的. 了解Android的朋友,一定知道Android四大组件,但对于进程可能会相对较陌生. 一个进程里面可以跑多个app(通过share uid的方式), 一个app也可以跑在多个进程里(通过配置Android:process属性).</p>    <p>再进一步进程是如何创建的, 可能很多人不知道fork的存在. 在我的文章 <a href="/misc/goto?guid=4959720056802377481" rel="nofollow,noindex">理解Android进程创建流程</a> 集中一点详细介绍了 Process.start 的过程是如何一步步创建进程.本文则是从另个角度来全局性讲解android进程启动全过程所涉及的根脉, 先来看看AMS.startProcessLocked方法.</p>    <h2><strong>二. 四大组件与进程</strong></h2>    <h3><strong>2.1 startProcessLocked</strong></h3>    <p>在 ActivityManagerService.java 关于启动进程有4个同名不同参数的重载方法, 为了便于说明,以下4个方法依次记为 1(a) , 1(b) , 2(a) , 2(b) :</p>    <pre>  <code class="language-java">//方法 1(a)  final ProcessRecord startProcessLocked(      String processName, ApplicationInfo info, boolean knownToBeDead,      int intentFlags, String hostingType, ComponentName hostingName,      boolean allowWhileBooting, boolean isolated, boolean keepIfLarge)    //方法 1(b)  final ProcessRecord startProcessLocked(      String processName, ApplicationInfo info, boolean knownToBeDead,      int intentFlags, String hostingType, ComponentName hostingName,      boolean allowWhileBooting, boolean isolated, int isolatedUid,      boolean keepIfLarge, String abiOverride, String entryPoint,      String[] entryPointArgs, Runnable crashHandler)    //方法 2(a)  private final void startProcessLocked(      ProcessRecord app, String hostingType, String hostingNameStr)    //方法 2(b)  private final void startProcessLocked(      ProcessRecord app, String hostingType, String hostingNameStr,      String abiOverride, String entryPoint, String[] entryPointArgs)</code></pre>    <p>1(a) ==> 1(b):方法1(a)将isolatedUid=0,其他参数赋值为null,再调用给1(b)</p>    <pre>  <code class="language-java">final ProcessRecord startProcessLocked(String processName,          ApplicationInfo info, boolean knownToBeDead, int intentFlags,          String hostingType, ComponentName hostingName, boolean allowWhileBooting,          boolean isolated, boolean keepIfLarge) {      return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,              hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,              null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,              null /* crashHandler */);  }</code></pre>    <p>2(a) ==> 2(b):方法2(a)将其他3个参数abiOverride,entryPoint, entryPointArgs赋值为null,再调用给2(b)</p>    <pre>  <code class="language-java">private final void startProcessLocked(ProcessRecord app,          String hostingType, String hostingNameStr) {      startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,              null /* entryPoint */, null /* entryPointArgs */);  }</code></pre>    <p>小结:</p>    <ul>     <li>1(a),1(b)的第一个参数为String类型的进程名processName,</li>     <li>2(a), 2(b)的第一个参数为ProcessRecord类型进程记录信息ProcessRecord;</li>     <li>1系列的方法最终调用到2系列的方法;</li>    </ul>    <h3><strong>2.2 四大组件与进程</strong></h3>    <p>Activity, Service, ContentProvider, BroadcastReceiver这四大组件,在启动的过程,当其所承载的进程不存在时需要先创建进程. 这个创建进程的过程是调用前面讲到的startProcessLocked方法1(a) . 调用流程: 1(a) => 1(b) ==> 2(b). 下面再简单说说这4大组件与进程创建是在何时需要创建的.</p>    <p>2.2.1 Activity</p>    <p>启动Activity过程: 调用startActivity,该方法经过层层调用,最终会调用ActivityStackSupervisor.java中的 startSpecificActivityLocked ,当activity所属进程还没启动的情况下,则需要创建相应的进程.</p>    <p>[-> ActivityStackSupervisor.java]</p>    <pre>  <code class="language-java">void startSpecificActivityLocked(...) {      ProcessRecord app = mService.getProcessRecordLocked(r.processName,              r.info.applicationInfo.uid, true);      if (app != null && app.thread != null) {          ...  //进程已创建的case          return      }      mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,                  "activity", r.intent.getComponent(), false, false, true);  }</code></pre>    <p>2.2.2 Service</p>    <p>启动服务过程: 调用startService,该方法经过层层调用,最终会调用ActiveServices.java中的 bringUpServiceLocked ,当Service进程没有启动的情况(app==null), 则需要创建相应的进程. 更多关于Service, 见startService流程分析</p>    <p>[-> ActiveServices.java]</p>    <pre>  <code class="language-java">private final String bringUpServiceLocked(...){      ...      ProcessRecord app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);      if (app == null) {          if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,                  "service", r.name, false, isolated, false)) == null) {              ...          }      }      ...  }</code></pre>    <p>2.2.3 ContentProvider</p>    <p>ContentProvider处理过程: 调用ContentResolver.query该方法经过层层调用, 最终会调用到AMS.java中的 getContentProviderImpl ,当ContentProvider所对应进程不存在,则需要创建新进程. 更多关于ContentProvider,见 <a href="/misc/goto?guid=4959713441761390939" rel="nofollow,noindex">理解ContentProvider原理(一)</a></p>    <p>[-> AMS.java]</p>    <pre>  <code class="language-java">private final ContentProviderHolder getContentProviderImpl(...) {      ...      ProcessRecord proc = getProcessRecordLocked(cpi.processName, cpr.appInfo.uid, false);      if (proc != null && proc.thread != null) {          ...  //进程已创建的case      } else {          proc = startProcessLocked(cpi.processName,                      cpr.appInfo, false, 0, "content provider",                      new ComponentName(cpi.applicationInfo.packageName,cpi.name),                      false, false, false);      }      ...  }</code></pre>    <p>2.2.4 Broadcast</p>    <p>广播处理过程: 调用sendBroadcast,该方法经过层层调用, 最终会调用到BroadcastQueue.java中的 processNextBroadcast ,当BroadcastReceiver所对应的进程尚未启动,则创建相应进程. 更多关于broadcast, 见 <a href="/misc/goto?guid=4959720056933178880" rel="nofollow,noindex">Android Broadcast广播机制分析</a> .</p>    <p>[-> BroadcastQueue.java]</p>    <pre>  <code class="language-java">final void processNextBroadcast(boolean fromMsg) {      ...      ProcessRecord app = mService.getProcessRecordLocked(targetProcess,          info.activityInfo.applicationInfo.uid, false);      if (app != null && app.thread != null) {          ...  //进程已创建的case          return      }        if ((r.curApp=mService.startProcessLocked(targetProcess,              info.activityInfo.applicationInfo, true,              r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,              "broadcast", r.curComponent,              (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))                      == null) {          ...      }      ...  }</code></pre>    <h3><strong>2.3 小节</strong></h3>    <p>Activity, Service, ContentProvider, BroadcastReceiver这四大组件在启动时,当所承载的进程不存在时,都需要创建. 进程的创建过程交由系统进程system_server来完成的.</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/1204e621a2a766e3cea67eba41f65865.jpg"></p>    <p>简称:</p>    <ul>     <li>ATP: ApplicationThreadProxy</li>     <li>AT: ApplicationThread (继承于ApplicationThreadNative)</li>     <li>AMP: ActivityManagerProxy</li>     <li>AMS: ActivityManagerService (继承于ActivityManagerNative)</li>    </ul>    <ol>     <li>system_server进程中调用 startProcessLocked 方法,该方法最终通过socket方式,将需要创建新进程的消息告知Zygote进程,并阻塞等待Socket返回新创建进程的pid;</li>     <li>Zygote进程接收到system_server发送过来的消息, 则通过fork的方法,将zygote自身进程复制生成新的进程,并将ActivityThread相关的资源加载到新进程app process,这个进程可能是用于承载activity等组件;</li>     <li>创建完新进程后fork返回两次, 在新进程app process向servicemanager查询system_server进程中binder服务端AMS,获取相对应的Client端,也就是AMP. 有了这一对binder c/s对, 那么app process便可以通过binder向跨进程system_server发送请求,即attachApplication()</li>     <li>system_server进程接收到相应binder操作后,经过多次调用,利用ATP向app process发送binder请求, 即bindApplication.</li>    </ol>    <p>system_server拥有ATP/AMS, 每一个新创建的进程都会有一个相应的AT/AMS,从而可以跨进程 进行相互通信. 这便是进程创建过程的完整生态链.</p>    <h2><strong>三. 进程启动全过程</strong></h2>    <p>前面刚已介绍四大组件的创建进程的过程是调用1(a) startProcessLocked 方法,该方法会再调用1(b)方法. 接下来从该方法开始往下讲述.</p>    <h3><strong>3.1 AMS.startProcessLocked</strong></h3>    <pre>  <code class="language-java">final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,          boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,          boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,          String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {      long startTime = SystemClock.elapsedRealtime();      ProcessRecord app;      if (!isolated) {          //根据进程名和uid检查相应的ProcessRecord          app = getProcessRecordLocked(processName, info.uid, keepIfLarge);            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {              //如果当前处于后台进程,检查当前进程是否处于bad进程列表              if (mBadProcesses.get(info.processName, info.uid) != null) {                  return null;              }          } else {              //当用户明确地启动进程,则清空crash次数,以保证其不处于bad进程直到下次再弹出crash对话框。              mProcessCrashTimes.remove(info.processName, info.uid);              if (mBadProcesses.get(info.processName, info.uid) != null) {                  mBadProcesses.remove(info.processName, info.uid);                  if (app != null) {                      app.bad = false;                  }              }          }      } else {          //对于孤立进程,无法再利用已存在的进程          app = null;      }        //当存在ProcessRecord,且已分配pid(正在启动或者已经启动),      // 且caller并不认为该进程已死亡或者没有thread对象attached到该进程.则不应该清理该进程      if (app != null && app.pid > 0) {          if (!knownToBeDead || app.thread == null) {              //如果这是进程中新package,则添加到列表              app.addPackage(info.packageName, info.versionCode, mProcessStats);              return app;          }          //当ProcessRecord已经被attached到先前的一个进程,则杀死并清理该进程          killProcessGroup(app.info.uid, app.pid);          handleAppDiedLocked(app, true, true);      }        String hostingNameStr = hostingName != null? hostingName.flattenToShortString() : null;      if (app == null) {          // 创建新的Process Record对象          app = newProcessRecordLocked(info, processName, isolated, isolatedUid);          if (app == null) {              return null;          }          app.crashHandler = crashHandler;      } else {          //如果这是进程中新package,则添加到列表          app.addPackage(info.packageName, info.versionCode, mProcessStats);      }      //当系统未准备完毕,则将当前进程加入到mProcessesOnHold      if (!mProcessesReady && !isAllowedWhileBooting(info) && !allowWhileBooting) {          if (!mProcessesOnHold.contains(app)) {              mProcessesOnHold.add(app);          }          return app;      }      // 启动进程【见小节3.2】      startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);      return (app.pid != 0) ? app : null;  }</code></pre>    <p>主要功能:</p>    <ul>     <li>对于非isolated进程,则根据进程名和uid来查询相应的ProcessRecord结构体. 如果当前进程处于后台且当前进程处于mBadProcesses列表,则直接返回;否则清空crash次数,以保证其不处于bad进程直到下次再弹出crash对话框。</li>     <li>当存在ProcessRecord,且已分配pid(正在启动或者已经启动)的情况下      <ul>       <li>当caller并不认为该进程已死亡或者没有thread对象attached到该进程.则不应该清理该进程,则直接返回;</li>       <li>否则杀死并清理该进程;</li>      </ul> </li>     <li>当ProcessRecord为空则新建一个,当创建失败则直接返回;</li>     <li>当系统未准备完毕,则将当前进程加入到mProcessesOnHold, 并直接返回;</li>     <li>最后启动新进程,其中参数含义:      <ul>       <li>hostingType可取值为”activity”,”service”,”broadcast”,”content provider”;</li>       <li>hostingNameStr数据类型为ComponentName,代表的是具体相对应的组件名.</li>      </ul> </li>    </ul>    <h3><strong>3.2 AMS.startProcessLocked</strong></h3>    <pre>  <code class="language-java">private final void startProcessLocked(ProcessRecord app, String hostingType,          String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {      long startTime = SystemClock.elapsedRealtime();      //当app的pid大于0且不是当前进程的pid,则从mPidsSelfLocked中移除该app.pid      if (app.pid > 0 && app.pid != MY_PID) {          synchronized (mPidsSelfLocked) {              mPidsSelfLocked.remove(app.pid);              mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);          }          app.setPid(0);      }      //从mProcessesOnHold移除该app      mProcessesOnHold.remove(app);      updateCpuStats(); //更新cpu统计信息      try {          try {              if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {                  //当前package已被冻结,则抛出异常                  throw new RuntimeException("Package " + app.info.packageName + " is frozen!");              }          } catch (RemoteException e) {              throw e.rethrowAsRuntimeException();          }          int uid = app.uid;          int[] gids = null;          int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;          if (!app.isolated) {              int[] permGids = null;              try {                  //通过Package Manager获取gids                  final IPackageManager pm = AppGlobals.getPackageManager();                  permGids = pm.getPackageGids(app.info.packageName, app.userId);                  MountServiceInternal mountServiceInternal = LocalServices.getService(                          MountServiceInternal.class);                  mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,                          app.info.packageName);              } catch (RemoteException e) {                  throw e.rethrowAsRuntimeException();              }                //添加共享app和gids,用于app直接共享资源              if (ArrayUtils.isEmpty(permGids)) {                  gids = new int[2];              } else {                  gids = new int[permGids.length + 2];                  System.arraycopy(permGids, 0, gids, 2, permGids.length);              }              gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));              gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));          }            //根据不同参数,设置相应的debugFlags          ...            app.gids = gids;          app.requiredAbi = requiredAbi;          app.instructionSet = instructionSet;            boolean isActivityProcess = (entryPoint == null);          if (entryPoint == null) entryPoint = "android.app.ActivityThread";          //请求Zygote创建新进程[见3.3]          Process.ProcessStartResult startResult = Process.start(entryPoint,                  app.processName, uid, uid, gids, debugFlags, mountExternal,                  app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,                  app.info.dataDir, entryPointArgs);            ...          if (app.persistent) {              Watchdog.getInstance().processStarted(app.processName, startResult.pid);          }          //重置ProcessRecord的成员变量          app.setPid(startResult.pid);          app.usingWrapper = startResult.usingWrapper;          app.removed = false;          app.killed = false;          app.killedByAm = false;            //将新创建的进程加入到mPidsSelfLocked          synchronized (mPidsSelfLocked) {              this.mPidsSelfLocked.put(startResult.pid, app);              if (isActivityProcess) {                  Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);                  msg.obj = app;                  //延迟发送消息PROC_START_TIMEOUT_MSG                  mHandler.sendMessageDelayed(msg, startResult.usingWrapper                          ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);              }          }      } catch (RuntimeException e) {          app.setPid(0); //进程创建失败,则重置pid      }  }</code></pre>    <ul>     <li>根据不同参数,设置相应的debugFlags,比如在AndroidManifest.xml中设置androidd:debuggable为true,代表app运行在debug模式,则增加debugger标识以及开启JNI check功能</li>     <li>调用Process.start来创建新进程;</li>     <li>重置ProcessRecord的成员变量, 一般情况下超时10s后发送PROC_START_TIMEOUT_MSG的handler消息;</li>    </ul>    <p>关于Process.start()是通过socket通信告知Zygote创建fork子进程,创建新进程后将ActivityThread类加载到新进程,并调用ActivityThread.main()方法。详细过程见 <a href="/misc/goto?guid=4959720056802377481" rel="nofollow,noindex">理解Android进程创建流程</a> ,接下来进入AT.main方法.</p>    <h3><strong>3.3 ActivityThread.main</strong></h3>    <p>[-> ActivityThread.java]</p>    <pre>  <code class="language-java">public static void main(String[] args) {      //性能统计默认是关闭的      SamplingProfilerIntegration.start();      //将当前进程所在userId赋值给sCurrentUser      Environment.initForCurrentUser();        EventLogger.setReporter(new EventLoggingReporter());      AndroidKeyStoreProvider.install();        //确保可信任的CA证书存放在正确的位置      final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());      TrustedCertificateStore.setDefaultUserDirectory(configDir);        Process.setArgV0("<pre-initialized>");        //创建主线程的Looper对象, 该Looper是不运行退出      Looper.prepareMainLooper();        //创建ActivityThread对象      ActivityThread thread = new ActivityThread();        //建立Binder通道 【见流程3.4】      thread.attach(false);      if (sMainThreadHandler == null) {          sMainThreadHandler = thread.getHandler();      }        // 当设置为true时,可打开消息队列的debug log信息      if (false) {          Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));      }      Looper.loop(); //消息循环运行      throw new RuntimeException("Main thread loop unexpectedly exited");  }</code></pre>    <ul>     <li> <p>创建主线程的Looper对象: 该Looper是不运行退出. 也就是说主线程的Looper是在进程创建完成时自动创建完成,如果子线程也需要创建handler通信过程,那么就需要手动创建Looper对象,并且每个线程只能创建一次.</p> </li>     <li> <p>创建ActivityThread对象 thread = new ActivityThread() : 该过程会初始化几个很重要的变量:</p>      <ul>       <li> <p>mAppThread = new ApplicationThread()</p> </li>       <li> <p>mLooper = Looper.myLooper()</p> </li>       <li> <p>mH = new H(), H 继承于 Handler ;用于处理组件的生命周期.</p> </li>      </ul> </li>     <li> <p>attach过程是当前主线程向system_server进程通信的过程, 将thread信息告知AMS.接下来还会进一步说明该过程.</p> </li>     <li> <p>sMainThreadHandler通过getHandler(),获取的对象便是 mH ,这就是主线程的handler对象.</p> </li>    </ul>    <p>之后主线程调用Looper.loop(),进入消息循环状态, 当没有消息时主线程进入休眠状态, 一旦有消息到来则唤醒主线程并执行相关操作.</p>    <h3><strong>3.4. ActivityThread.attach</strong></h3>    <p>[-> ActivityThread.java]</p>    <pre>  <code class="language-java">private void attach(boolean system) {      sCurrentActivityThread = this;      mSystemThread = system;      if (!system) {           //开启虚拟机的jit即时编译功能          ViewRootImpl.addFirstDrawHandler(new Runnable() {              @Override              public void run() {                  ensureJitEnabled();              }          });          android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());            RuntimeInit.setApplicationObject(mAppThread.asBinder());          //创建ActivityManagerProxy对象          final IActivityManager mgr = ActivityManagerNative.getDefault();          try {              //调用基于IActivityManager接口的Binder通道【见流程3.5】              mgr.attachApplication(mAppThread);          } catch (RemoteException ex) {          }            //观察是否快接近heap的上限          BinderInternal.addGcWatcher(new Runnable() {              @Override public void run() {                  if (!mSomeActivitiesChanged) {                      return;                  }                  Runtime runtime = Runtime.getRuntime();                  long dalvikMax = runtime.maxMemory();                  long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();                  if (dalvikUsed > ((3*dalvikMax)/4)) {                      mSomeActivitiesChanged = false;                      try {                          //当已用内存超过最大内存的3/4,则请求释放内存空间                          mgr.releaseSomeActivities(mAppThread);                      } catch (RemoteException e) {                      }                  }              }          });      } else {          ...      }      //添加dropbox日志到libcore      DropBox.setReporter(new DropBoxReporter());        //添加Config回调接口      ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {          @Override          public void onConfigurationChanged(Configuration newConfig) {              synchronized (mResourcesManager) {                  if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {                      if (mPendingConfiguration == null ||                              mPendingConfiguration.isOtherSeqNewer(newConfig)) {                          mPendingConfiguration = newConfig;                          sendMessage(H.CONFIGURATION_CHANGED, newConfig);                      }                  }              }          }          @Override          public void onLowMemory() {          }          @Override          public void onTrimMemory(int level) {          }      });  }</code></pre>    <p>对于非系统attach的处理流程:</p>    <ul>     <li> <p>创建线程来开启虚拟机的jit即时编译;</p> </li>     <li> <p>通过binder, 调用到AMS.attachApplication, 其参数mAppThread的数据类型为 ApplicationThread</p> </li>     <li> <p>观察是否快接近heap的上限,当已用内存超过最大内存的3/4,则请求释放内存空间</p> </li>     <li> <p>添加dropbox日志到libcore</p> </li>     <li> <p>添加Config回调接口</p> </li>    </ul>    <h3><strong>3.5 AMP.attachApplication</strong></h3>    <p>[-> ActivityManagerProxy.java]</p>    <pre>  <code class="language-java">public void attachApplication(IApplicationThread app) throws RemoteException  {      Parcel data = Parcel.obtain();      Parcel reply = Parcel.obtain();      data.writeInterfaceToken(IActivityManager.descriptor);      data.writeStrongBinder(app.asBinder());      mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); //【见流程3.6】      reply.readException();      data.recycle();      reply.recycle();  }</code></pre>    <p>此处 descriptor = “android.app.IActivityManager”</p>    <h3><strong>3.6 AMN.onTransact</strong></h3>    <p>[-> ActivityManagerNative.java]</p>    <pre>  <code class="language-java">public boolean onTransact(int code, Parcel data, Parcel reply, int flags)          throws RemoteException {      switch (code) {      ...       case ATTACH_APPLICATION_TRANSACTION: {          data.enforceInterface(IActivityManager.descriptor);          //获取ApplicationThread的binder代理类 ApplicationThreadProxy          IApplicationThread app = ApplicationThreadNative.asInterface(                  data.readStrongBinder());          if (app != null) {              attachApplication(app); //此处是ActivityManagerService类中的方法 【见流程3.7】          }          reply.writeNoException();          return true;      }      }  }</code></pre>    <h3><strong>3.7 AMS.attachApplication</strong></h3>    <p>[-> ActivityManagerService.java]</p>    <pre>  <code class="language-java">public final void attachApplication(IApplicationThread thread) {      synchronized (this) {          int callingPid = Binder.getCallingPid();          final long origId = Binder.clearCallingIdentity();          attachApplicationLocked(thread, callingPid); // 【见流程3.8】          Binder.restoreCallingIdentity(origId);      }  }</code></pre>    <p>此处的 thread 便是ApplicationThreadProxy对象,用于跟前面通过Process.start()所创建的进程中ApplicationThread对象进行通信.</p>    <h3><strong>3.8 AMS.attachApplicationLocked</strong></h3>    <p>[-> ActivityManagerService.java]</p>    <pre>  <code class="language-java">private final boolean attachApplicationLocked(IApplicationThread thread,          int pid) {      ProcessRecord app;      if (pid != MY_PID && pid >= 0) {          synchronized (mPidsSelfLocked) {              app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord          }      } else {          app = null;      }      if (app == null) {          if (pid > 0 && pid != MY_PID) {              //ProcessRecord为空,则杀掉该进程              Process.killProcessQuiet(pid);          } else {              //退出新建进程的Looper              thread.scheduleExit();          }          return false;      }        //还刚进入attach过程,此时thread应该为null,若不为null则表示该app附到上一个进程,则立刻清空      if (app.thread != null) {          handleAppDiedLocked(app, true, true);      }        final String processName = app.processName;      try {          //绑定死亡通知          AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);          thread.asBinder().linkToDeath(adr, 0);          app.deathRecipient = adr;      } catch (RemoteException e) {          app.resetPackageList(mProcessStats);          startProcessLocked(app, "link fail", processName); //重新启动进程          return false;      }        //重置进程信息      app.makeActive(thread, mProcessStats); //执行完该语句,则app.thread便不再为空      app.curAdj = app.setAdj = -100;      app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;      app.forcingToForeground = null;      updateProcessForegroundLocked(app, false, false);      app.hasShownUi = false;      app.debugging = false;      app.cached = false;      app.killedByAm = false;      mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); //移除进程启动超时的消息        //系统处于ready状态或者该app为FLAG_PERSISTENT进程,则为true      boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);      List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;        //app进程存在正在启动中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息      if (providers != null && checkAppInLaunchingProvidersLocked(app)) {          Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);          msg.obj = app;          mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);      }        try {          ...          ensurePackageDexOpt(app.instrumentationInfo != null                  ? app.instrumentationInfo.packageName                  : app.info.packageName);            ApplicationInfo appInfo = app.instrumentationInfo != null                  ? app.instrumentationInfo : app.info;          ...          // 绑定应用 [见流程3.9]          thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,                  profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,                  app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,                  isRestrictedBackupMode || !normalMode, app.persistent,                  new Configuration(mConfiguration), app.compat,                  getCommonServicesLocked(app.isolated),                  mCoreSettingsObserver.getCoreSettingsLocked());          //更新进程LRU队列          updateLruProcessLocked(app, false, null);          app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();      } catch (Exception e) {          app.resetPackageList(mProcessStats);          app.unlinkDeathRecipient();          //每当bind操作失败,则重启启动进程, 此处有可能会导致进程无限重启          startProcessLocked(app, "bind fail", processName);          return false;      }        mPersistentStartingProcesses.remove(app);      mProcessesOnHold.remove(app);      boolean badApp = false;      boolean didSomething = false;        //Activity: 检查最顶层可见的Activity是否等待在该进程中运行      if (normalMode) {          try {              if (mStackSupervisor.attachApplicationLocked(app)) {                  didSomething = true;              }          } catch (Exception e) {              badApp = true;          }      }        //Service: 寻找所有需要在该进程中运行的服务      if (!badApp) {          try {              didSomething |= mServices.attachApplicationLocked(app, processName);          } catch (Exception e) {              badApp = true;          }      }      //广播:检查是否在这个进程中有下一个广播接收者      if (!badApp && isPendingBroadcastProcessLocked(pid)) {          try {              didSomething |= sendPendingBroadcastsLocked(app);          } catch (Exception e) {              badApp = true;          }      }      //检查是否在这个进程中有下一个backup代理      if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {          ensurePackageDexOpt(mBackupTarget.appInfo.packageName);          try {              thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,                      compatibilityInfoForPackageLocked(mBackupTarget.appInfo),                      mBackupTarget.backupMode);          } catch (Exception e) {              badApp = true;          }      }      if (badApp) { //杀掉bad应用          app.kill("error during init", true);          handleAppDiedLocked(app, false, true);          return false;      }      if (!didSomething) {          updateOomAdjLocked(); //更新adj的值      }      return true;  }</code></pre>    <ol>     <li> <p>根据pid从mPidsSelfLocked中查询到相应的ProcessRecord对象app;</p> </li>     <li> <p>当app==null,意味着本次创建的进程不存在, 则直接返回.</p> </li>     <li> <p>还刚进入attach过程,此时thread应该为null,若不为null则表示该app附到上一个进程,则调用handleAppDiedLocked清理.</p> </li>     <li> <p>绑定死亡通知,当进程pid死亡时会通过binder死亡回调,来通知system_server进程死亡的消息;</p> </li>     <li> <p>重置ProcessRecord进程信息, 此时app.thread也赋予了新值,便不再为空.</p> </li>     <li> <p>app进程存在正在启动中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息</p> </li>     <li> <p>调用thread.bindApplication绑定应用进程, 后面再进一步说明</p> </li>     <li> <p>处理Provider, Activity, Service, Broadcast相应流程</p> </li>    </ol>    <p>下面,再来说说thread.bindApplication的过程.</p>    <h3><strong>3.9 ATP.bindApplication</strong></h3>    <p>[-> ApplicationThreadNative.java ::ApplicationThreadProxy]</p>    <pre>  <code class="language-java">class ApplicationThreadProxy implements IApplicationThread {      ...      public final void bindApplication(String packageName, ApplicationInfo info,              List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo,              Bundle testArgs, IInstrumentationWatcher testWatcher,              IUiAutomationConnection uiAutomationConnection, int debugMode,              boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,              Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,              Bundle coreSettings) throws RemoteException {          Parcel data = Parcel.obtain();          data.writeInterfaceToken(IApplicationThread.descriptor);          data.writeString(packageName);          info.writeToParcel(data, 0);          data.writeTypedList(providers);          if (testName == null) {              data.writeInt(0);          } else {              data.writeInt(1);              testName.writeToParcel(data, 0);          }          if (profilerInfo != null) {              data.writeInt(1);              profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);          } else {              data.writeInt(0);          }          data.writeBundle(testArgs);          data.writeStrongInterface(testWatcher);          data.writeStrongInterface(uiAutomationConnection);          data.writeInt(debugMode);          data.writeInt(openGlTrace ? 1 : 0);          data.writeInt(restrictedBackupMode ? 1 : 0);          data.writeInt(persistent ? 1 : 0);          config.writeToParcel(data, 0);          compatInfo.writeToParcel(data, 0);          data.writeMap(services);          data.writeBundle(coreSettings);          mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,                  IBinder.FLAG_ONEWAY);          data.recycle();      }      ...  }</code></pre>    <p>ATP经过binder ipc传递到ATN的onTransact过程.</p>    <h3><strong>3.10 ATN.onTransact</strong></h3>    <p>[-> ApplicationThreadNative.java]</p>    <pre>  <code class="language-java">public boolean onTransact(int code, Parcel data, Parcel reply, int flags)          throws RemoteException {      switch (code) {      ...      case BIND_APPLICATION_TRANSACTION:      {          data.enforceInterface(IApplicationThread.descriptor);          String packageName = data.readString();          ApplicationInfo info =              ApplicationInfo.CREATOR.createFromParcel(data);          List<ProviderInfo> providers =              data.createTypedArrayList(ProviderInfo.CREATOR);          ComponentName testName = (data.readInt() != 0)              ? new ComponentName(data) : null;          ProfilerInfo profilerInfo = data.readInt() != 0                  ? ProfilerInfo.CREATOR.createFromParcel(data) : null;          Bundle testArgs = data.readBundle();          IBinder binder = data.readStrongBinder();          IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);          binder = data.readStrongBinder();          IUiAutomationConnection uiAutomationConnection =                  IUiAutomationConnection.Stub.asInterface(binder);          int testMode = data.readInt();          boolean openGlTrace = data.readInt() != 0;          boolean restrictedBackupMode = (data.readInt() != 0);          boolean persistent = (data.readInt() != 0);          Configuration config = Configuration.CREATOR.createFromParcel(data);          CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);          HashMap<String, IBinder> services = data.readHashMap(null);          Bundle coreSettings = data.readBundle();          //[见流程3.11]          bindApplication(packageName, info, providers, testName, profilerInfo, testArgs,                  testWatcher, uiAutomationConnection, testMode, openGlTrace,                  restrictedBackupMode, persistent, config, compatInfo, services, coreSettings);          return true;      }      ...  }</code></pre>    <h3><strong>3.11 AT.bindApplication</strong></h3>    <p>[-> ActivityThread.java ::ApplicationThread]</p>    <pre>  <code class="language-java">public final void bindApplication(String processName, ApplicationInfo appInfo,          List<ProviderInfo> providers, ComponentName instrumentationName,          ProfilerInfo profilerInfo, Bundle instrumentationArgs,          IInstrumentationWatcher instrumentationWatcher,          IUiAutomationConnection instrumentationUiConnection, int debugMode,          boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,          Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,          Bundle coreSettings) {        if (services != null) {          //将services缓存起来, 减少binder检索服务的次数          ServiceManager.initServiceCache(services);      }        //发送消息H.SET_CORE_SETTINGS      setCoreSettings(coreSettings);        IPackageManager pm = getPackageManager();      android.content.pm.PackageInfo pi = null;      try {          pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());      } catch (RemoteException e) {      }      if (pi != null) {          boolean sharedUserIdSet = (pi.sharedUserId != null);          boolean processNameNotDefault = (pi.applicationInfo != null &&           !appInfo.packageName.equals(pi.applicationInfo.processName));          boolean sharable = (sharedUserIdSet || processNameNotDefault);            if (!sharable) {              VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,                                      appInfo.processName);          }      }        //初始化AppBindData, 再发送消息H.BIND_APPLICATION      AppBindData data = new AppBindData();      data.processName = processName;      data.appInfo = appInfo;      data.providers = providers;      data.instrumentationName = instrumentationName;      data.instrumentationArgs = instrumentationArgs;      data.instrumentationWatcher = instrumentationWatcher;      data.instrumentationUiAutomationConnection = instrumentationUiConnection;      data.debugMode = debugMode;      data.enableOpenGlTrace = enableOpenGlTrace;      data.restrictedBackupMode = isRestrictedBackupMode;      data.persistent = persistent;      data.config = config;      data.compatInfo = compatInfo;      data.initProfilerInfo = profilerInfo;      sendMessage(H.BIND_APPLICATION, data);  }</code></pre>    <p>其中setCoreSettings()过程就是调用sendMessage(H.SET_CORE_SETTINGS, coreSettings) 来向主线程发送SET_CORE_SETTINGS消息.bindApplication方法的主要功能是依次向主线程发送消息 H.SET_CORE_SETTINGS 和 H.BIND_APPLICATION . 接下来再来说说这两个消息的处理过程</p>    <h3><strong>3.12 H.SET_CORE_SETTINGS</strong></h3>    <p>[-> ActivityThread.java ::H]</p>    <p>当主线程收到H.SET_CORE_SETTINGS,则调用handleSetCoreSettings</p>    <pre>  <code class="language-java">private void handleSetCoreSettings(Bundle coreSettings) {      synchronized (mResourcesManager) {          mCoreSettings = coreSettings;      }      onCoreSettingsChange();  }    private void onCoreSettingsChange() {      boolean debugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;      if (debugViewAttributes != View.mDebugViewAttributes) {          View.mDebugViewAttributes = debugViewAttributes;            // 由于发生改变, 请求所有的activities重启启动          for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {              requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false);          }      }  }</code></pre>    <h3><strong>3.13 H.BIND_APPLICATION</strong></h3>    <p>[-> ActivityThread.java ::H]</p>    <p>当主线程收到H.BIND_APPLICATION,则调用handleBindApplication</p>    <pre>  <code class="language-java">private void handleBindApplication(AppBindData data) {        mBoundApplication = data;      mConfiguration = new Configuration(data.config);      mCompatConfiguration = new Configuration(data.config);        ...        //设置进程名      Process.setArgV0(data.processName);      android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());        if (data.persistent) {          //低内存设备, persistent进程不采用硬件加速绘制,以节省内存使用量          if (!ActivityManager.isHighEndGfx()) {              HardwareRenderer.disable(false);          }      }        //重置时区      TimeZone.setDefault(null);      Locale.setDefault(data.config.locale);        //更新系统配置      mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);      mCurDefaultDisplayDpi = data.config.densityDpi;      applyCompatConfiguration(mCurDefaultDisplayDpi);        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);      ...        // 创建ContextImpl上下文      final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);      if (!Process.isIsolated()) {          final File cacheDir = appContext.getCacheDir();          if (cacheDir != null) {              System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());          }            //用于存储产生/编译的图形代码          final File codeCacheDir = appContext.getCodeCacheDir();          if (codeCacheDir != null) {              setupGraphicsSupport(data.info, codeCacheDir);          }      }          final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));      DateFormat.set24HourTimePref(is24Hr);        View.mDebugViewAttributes =  mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;        ...        //当处于调试模式,则运行应用生成systrace信息      boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;      Trace.setAppTracingAllowed(appTracingAllowed);        //初始化 默认的http代理      IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);      if (b != null) {          IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);          final ProxyInfo proxyInfo = service.getProxyForNetwork(null);          Proxy.setHttpProxySystemProperty(proxyInfo);      }        if (data.instrumentationName != null) {          InstrumentationInfo ii = null;          ii = appContext.getPackageManager().getInstrumentationInfo(data.instrumentationName, 0);            mInstrumentationPackageName = ii.packageName;          mInstrumentationAppDir = ii.sourceDir;          mInstrumentationSplitAppDirs = ii.splitSourceDirs;          mInstrumentationLibDir = ii.nativeLibraryDir;          mInstrumentedAppDir = data.info.getAppDir();          mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();          mInstrumentedLibDir = data.info.getLibDir();            ApplicationInfo instrApp = new ApplicationInfo();          instrApp.packageName = ii.packageName;          instrApp.sourceDir = ii.sourceDir;          instrApp.publicSourceDir = ii.publicSourceDir;          instrApp.splitSourceDirs = ii.splitSourceDirs;          instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;          instrApp.dataDir = ii.dataDir;          instrApp.nativeLibraryDir = ii.nativeLibraryDir;          LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,                  appContext.getClassLoader(), false, true, false);          ContextImpl instrContext = ContextImpl.createAppContext(this, pi);            //通过反射,创建目标类          java.lang.ClassLoader cl = instrContext.getClassLoader();          mInstrumentation = (Instrumentation)              cl.loadClass(data.instrumentationName.getClassName()).newInstance();              mInstrumentation.init(this, instrContext, appContext,                 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,                 data.instrumentationUiAutomationConnection);          ...      } else {          mInstrumentation = new Instrumentation();      }        //FLAG_LARGE_HEAP则清除内存增长上限      if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {          dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();      } else {          dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();      }        try {          Application app = data.info.makeApplication(data.restrictedBackupMode, null);          mInitialApplication = app;            if (!data.restrictedBackupMode) {              List<ProviderInfo> providers = data.providers;              if (providers != null) {                  installContentProviders(app, providers);                  mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);              }          }            mInstrumentation.onCreate(data.instrumentationArgs);          //调用app.onCreate()方法.          mInstrumentation.callApplicationOnCreate(app);        } finally {          StrictMode.setThreadPolicy(savedPolicy);      }  }</code></pre>    <h2><strong>四. 总结</strong></h2>    <p>本文首先介绍AMS的4个同名不同参数的方法startProcessLocked; 紧接着讲述了四大组件与进程的关系, Activity, Service, ContentProvider, BroadcastReceiver这四大组件,在启动的过程,当其所承载的进程不存在时需要先创建进程. 再然后进入重点以startProcessLocked以引线一路讲解整个过程所遇到的核心方法. 在整个过程中有新创建的进程与system_server进程之间的交互过程 是通过binder进行通信的, 这里有两条binder通道分别为AMP/AMN 和 ATP/ATN.</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a678656b4fb8f43dc79947a600a61e4b.jpg"></p>    <p>上图便是一次完整的进程创建过程,app的任何组件需要有一个承载其运行的容器,那就是进程, 那么进程的创建过程都是由系统进程system_server通过socket向zygote进程来请求fork()新进程, 当创建出来的app process与system_server进程之间的通信便是通过binder IPC机制.</p>    <p> </p>    <p> </p>    <p>来自:http://gityuan.com/2016/10/09/app-process-create-2/</p>    <p> </p>