进程启动学习

https://blog.csdn.net/yun_hen/article/details/78590991    上一个activity的暂停、进程启动、绑定进程与创建

https://blog.csdn.net/huaxun66/article/details/78151361

application的网址

一、AMS的进程的启动  

  1. startProcessLocked (......)  {

     .....

   try {
   try {
     final int userId = UserHandle.getUserId(app.uid);
     AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
    } catch (RemoteException e) {
      throw e.rethrowAsRuntimeException();
    }
    int uid = app.uid;
    int[] gids = null;
    int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
    /*
    * Add shared application and profile GIDs so applications can share some
    * resources like shared libraries and access user-wide resources
    */   这里可以添加你想要的组的其他ID数值
    if (ArrayUtils.isEmpty(permGids)) {
      gids = new int[3];
    } else {
    gids = new int[permGids.length + 3];
    System.arraycopy(permGids, 0, gids, 3, permGids.length);
  }
  gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
  gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
  gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
  
  // Replace any invalid GIDs
  if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
  if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];

  // MIUI ADD
  // EP MOD: START
  // gids = ActivityManagerServiceInjector.computeGids(UserHandle.getUserId(uid), gids, app);
  gids = ActivityManagerServiceInjector.computeGids(mContext, UserHandle.getUserId(uid), gids, app);
  // END
  }

  ........

  //这段代码可以孵化出一个进程的启动和

  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);

  }

  二、AMS常用的文件介绍

    1.Activity.java : 所有Activity的父类

    2.ActivityThread :  该类是应用程序对应的进程的主线程类,即UI线程

    3.ActiityRecord :  activity的记录对象

    4.ActivityStack 、ActivityStackSupervisor : 管理activity的启动,生命周期以及activity的堆栈等

    5.ProcessRecord  :  该类用于记录每个进程的全部信息。主要信息包括该进程包含的activity、provider、service等信息、进程文件信息、进程状态信息

    6.TaskRecord  :  应用activity记录任务栈

    7.ActiveServices、ActiveServiceEx  :  控制service的启动,重启等

    8.BroadcastQueue :  管理广播的发送

    9.ServiceRecord  :  service 的记录对象

  三、 activity的启动大致流程图

    

   四、准备创建activity

        

       1. AMS --->  startActivity(.....) ----> startActivityAsUser(......)

       2.  startActivityMayWait(....)      ActivityStarter.java

        //通过PMS解析意图

        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);

        //...

        //获取该意图的活动对象Activity的Info信息,里面有需要启动应用的信息如包名test2

        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        //这里才是真正启动应用的地方

        int res = startActivity(caller, intent, ephemeralIntent, resolvedType,

        //...

        //outResult输出activity的启动结果,一般自动化测试的中使用

        if (outResult != null) {

        //...

         do {

           try {

           //只有等到mService.notify()或者mService.notifyAll()此处才会继续执行下去

          mService.wait(); } catch (InterruptedException e) { } } while (outResult.result != START_TASK_TO_FRONT && !outResult.timeout && outResult.who == null); //... } ... }

        3.   startActivity(.......)  ActivityStarter.java

          作用:创建一个即将要启动的Activity的ActivityRecord对象

           //...

          //新建需要启动活动对象activity(如test2)的ActivityRecord

          ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord,

          resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, container, options, sourceRecord);

           //...

          //看看之前是否还有未启动的活动对象

          doPendingActivityLaunchesLocked(false);

           //...

          //这里是真正起到进程的地方,倒数第三个参数doResume=true

          err = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);
        
4.   startActivity (.....)   ActivityStarter.java

          1).  此处会启动新的ActivityStack,输出am_create_task

          2).  输出am_create_task,准备创建activity

          3).  设置焦点、焦点切换

          4).  上一个activity的onpause的状态

          5). 处理的工作就是Activity四种启动模式的处理

           //...

          //初始化一些参数,如mUserLeaving==true就是在这里设置的

          setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor);

          //...

          if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {

            newTask = true;

            //这里会进来,启动新的ActivityStack  mTargetStack

            setTaskFromReuseOrCreateNewTask(taskToAffiliate);

            //... }

         if (newTask) {

          //属于新的task,会在event log中输出am_create_task

          EventLog.writeEvent( EventLogTags.AM_CREATE_TASK, mStartActivity.userId, mStartActivity.task.taskId); }

          //event log中输出am_create_activity,开始启动应用

          ActivityStack.logStartActivity( EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.task);

          //...

           //stack中的startActivityLocked,此处设置mStartActivity.task(TaskRecord)的

          //topRunningActivityLocked为test2

         mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);

         //mDoResume == true,会进入此处

         if (mDoResume) {

         //...

         if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
           mTargetStack.moveToFront("startActivityUnchecked");
         }
         mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);

        

                                 三者之间的关系

      5.   void moveToFront(String reason, TaskRecord task)    :   ActivityStack.java

         //...

           //此处会设置mFocusedStack为当前需要启动的activity,如test2.com.myapplication

         //getFocusedStack时就会是test2

             mStackSupervisor.setFocusStackUnchecked(reason, this);

            if (task != null) {

           //此处是修改activity的task,会将test2放在mTaskHistory中,

          //当调用topRunningActivityLocked(ActivityStack)判断顶端activity的时候就会返回test2

        insertTaskAtTop(task, null); }
      6.  setFocusStackUnchecked(.......)     ActivityStackSupervisor.java

        //...

        //如果需要设置的焦点focusCandidate和之前focus的不一样,会进入此处

        if (focusCandidate != mFocusedStack) {

          //更新堆栈焦点状态

          mLastFocusedStack = mFocusedStack;

          mFocusedStack = focusCandidate;

          //....

    五、焦点切换流程

       

      1startActivityLocked(.......)  ActivityStarter.java

           //...

          //新建需要启动活动对象activity(如test2)的ActivityRecord

          ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord,

          resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, container, options, sourceRecord);

           //...

          //看看之前是否还有未启动的活动对象

          doPendingActivityLaunchesLocked(false);

           //...

          //这里是真正起到进程的地方,倒数第三个参数doResume=true

          err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);

  
       2.   startActivityUnchecked (.....)

           //...

          //初始化一些参数,如mUserLeaving==true就是在这里设置的

          setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor);

          //...

          if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {

            newTask = true;

            //这里会进来,启动新的ActivityStack  mTargetStack

            setTaskFromReuseOrCreateNewTask(taskToAffiliate);

            //... }

           if (newTask) {

          //属于新的task,会在event log中输出am_create_task

          EventLog.writeEvent( EventLogTags.AM_CREATE_TASK, mStartActivity.userId, mStartActivity.task.taskId); }

          //event log中输出am_create_activity,开始启动应用

          ActivityStack.logStartActivity( EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.task);

          //...

           //stack中的startActivityLocked,此处设置mStartActivity.task(TaskRecord)的

          //topRunningActivityLocked为test2

          mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);

          //mDoResume == true,会进入此处

          if (mDoResume) {

             //.....

          if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
          mTargetStack.moveToFront("startActivityUnchecked");
         }
         mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);

         //.....

      }

      3.  void moveToFront(String reason, TaskRecord task)    :   ActivityStack.java

         //...

           //此处会设置mFocusedStack为当前需要启动的activity,如test2.com.myapplication

         //getFocusedStack时就会是test2

             mStackSupervisor.setFocusStackUnchecked(reason, this);

            if (task != null) {

           //此处是修改activity的task,会将test2放在mTaskHistory中,

          //当调用topRunningActivityLocked(ActivityStack)判断顶端activity的时候就会返回test2

        insertTaskAtTop(task, null); }
      4.  setFocusStackUnchecked(.......)     ActivityStackSupervisor.java

        //...

        //如果需要设置的焦点focusCandidate和之前focus的不一样,会进入此处

        if (focusCandidate != mFocusedStack) {

          //更新堆栈焦点状态

          mLastFocusedStack = mFocusedStack;

          mFocusedStack = focusCandidate;

          //....

 

     

    六、上一个activity的暂停、进程启动、绑定进程与创建application

        

 

     1. startActivityUnchecked (.....)   ActivityStarter.java暂停activity之后会接着调用

                            resumeFocusedStackTopActivityLocked(....)  ActivityStackSupervisor.java

     2.  resumeFocusedStackTopActivityLocked(....)   ActivityStackSupervisor.java

           if (targetStack != null && isFocusedStack(targetStack)) {

          //targetStack不为null,而且isFocusedStack也是test2,故此处是会进来的

          return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } //... }


     3.  resumeTopActivityUncheckedLocked(.......)ActivityStack.java  :  恢复当前focus堆栈stack中的顶端活动对象

          //....

          result = resumeTopActivityInnerLocked(prev, options);

         //....

     4.  resumeTopActivityInnerLocked(....)   ActivityStack.java

          //...

        //第一次进来topRunningActivityLocked是test2,第二次进来也是test2,

        //此处是在moveActivityStackToFront中已经设置过了

        final ActivityRecord next = topRunningActivityLocked();

        //...

        //此处allPausedActivitiesComplete是true,不会进入这里,

        //说明之前已经没有需要pause的应用(第一次进来mPausingActivity还没有设置过==null)

        //或者pause完成(第二次进来)

        if (!mStackSupervisor.allPausedActivitiesComplete()) {

          …

          return false; }

          //...

          //此处判断是否有需要pasue的进程(是所有stack而不仅仅是当前stack),

          //第一次进来会pause launcher(launcher的堆栈中有mResumedActivity,

          //但是章节4.2已经将焦点切换到test2)故反馈pausing==true,第二次直接返回pausing==false

          boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);

          //mResumedActivity一直都是null(由于当前mTargetStack是新new出来的给进程test2使用),

          //只有在test2 resume之后才会设置,如在minimalResumeActivityLocked之后设置,故不会走下面的逻辑

          if (mResumedActivity != null) { //... }

          //第一次走的pausing是true(代表有需要暂停的应用,如launcher),第二次pausing是false

          if (pausing) {

            //...

            //第一次进来到这里就结束了

            return true;

            //此处一般都是不走的mResumedActivity == null,第二次pausing是false,

            //但是还是有activity继续resume(allResumedActivitiesComplete返回false)

          } else if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) {

            //...

            return true; }

          //第二次时会进来这里prev != next,此处next代表test2.com.myapplication,

          //prev代表com.android.launcher

          if (prev != null && prev != next) {

            if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev) && next != null && !next.nowVisible)

            {

              //等待prev的界面launcher隐藏,此处在mStackSupervisor的

              //processStoppingActivitiesLocked时才会remove

              mStackSupervisor.mWaitingVisibleActivities.add(prev);

            } else { //... }

            //...

             //第二次进来时prev == com.android.launcher

            if (prev != null) {

              //launcher是没有finishing的,不进入这里

              if (prev.finishing) {

                //...

                //准备resume test2.com.myapplication时prev代表com.android.launcher,会进来这里

              } else {

              //prev.task不等于next.task,mLaunchTaskBehind是false,

              //WMS中传输类型是TRANSIT_TASK_OPEN

              mWindowManager.prepareAppTransition(prev.task == next.task ? TRANSIT_ACTIVITY_OPEN : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND : TRANSIT_TASK_OPEN, false); 

               } else {

              //...

              }

              //...

              //此处next(test2.com.myapplication)进程都还没有起来,不会进入这里

                if (next.app != null && next.app.thread != null) {

                //...

                 //next(test2.com.myapplication)进入的是else

              } else {

                //第一次启动hasBeenLaunched肯定是false,所以会进入此处

                if (!next.hasBeenLaunched) {

                  next.hasBeenLaunched = true;

                } else { ... }

                //这里才是真正启动test2进程的地方, 启动指定的AttivityRecored

                mStackSupervisor.startSpecificActivityLocked(next, true, true); }

                //...

      5.  pauseBackStacks(....) ActivityStackSupervisor.java :  遍历ActivityDisplay显示设备中的所有栈,当循环到luancher的时候,             由于launcher已经不是focus的stack栈,但是它的mResumedActivity仍然存在,代表这个activity需要进行pause暂停的操作

             boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {

              //...

              //遍历stacks当前显示设备的所有堆栈

              final ActivityStack stack = stacks.get(stackNdx);

              //stack是launcher,isFocusedStack是false,mResumedActivity是launcher不等于null

              if (!isFocusedStack(stack) && stack.mResumedActivity != null) {

                //launcher的stack进行pause的操作,注意resuming是true,dontWait是false,

                //userLeaving是true,在章节3.6 startActivityUnchecked->setInitialState中设置

                someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, dontWait);    上一个Activity即将进入onPaused状态

              //... }
      6. startPausingLocked(ActivityStack.java) 

        1) startPausingLocked这个函数是启动应用暂停pause(如此处的是上一个应用launcher),设置当前状态为pausing
        2) 进入ActivityThread处理暂停任务之前会在eventlog中输出am_pause_activity的信息,表示将要开始该应用的暂停了
        3) 不过最重要的函数还是ActivityThread的schedulePauseActivity,该函数会处理pause任务

             //userLeaving==true, uiSleeping==false, resuming==true, dontWait==false
             final boolean startPausingLocked(.....) {
             //第一次进来mPausingActivity是null,应用没有暂停就没有所谓的mPausingActivity
             if (mPausingActivity != null) {
             //...
             }
             //mResumedActivity是当前resume的activity,此处是launcher
             ActivityRecord prev = mResumedActivity;
             //注意此处pause之后将设置mResumedActivity==null,代表没有该Stack没有resume的activity了
             mResumedActivity = null;
             //launcher设置为正在pause的进程 mPausingActivity = prev;
             //设置上一个暂停的应用 mLastPausedActivity = prev;
             //标定该进程在PAUSING状态
             prev.state = ActivityState.PAUSING;
             //此处next是test2,章节4.2的insertTaskAtTop已经设置过
             final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
             //pause应用会触发cpu状态更新,可以使用adb shell dumpsys cpuinfo查询
             mService.updateCpuStats();
             //prev是launcher,里面的app和thread都是已经创建的,所有此处会进入
             if (prev.app != null && prev.app.thread != null) {
             try {
             //event log中的am_pause_activity,代表应用的pause开始
             EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, prev.userId, System.identityHashCode(prev),                    prev.shortComponentName);
             //cpu前后台切换,用于耗电统计
             mService.updateUsageStats(prev, false);
             //ActivityThread里面的方法是handle(异步),此处才是activity的真正的pause执行的地方
               prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait);
            //...
            //mPausingActivity就是launcher,所以会进来此处。
            if (mPausingActivity != null) {
            //uiSleeping==false
            if (!uiSleeping) {
            //应用的pause的时候,会暂停接收输入事件,此时系统触摸了不反馈给上层
            prev.pauseKeyDispatchingLocked(); }
            //dontWait==false,章节5.2中设置dontWaitForPause
            if (dontWait) {
            //只有当dontWait是true的时候才会走这里,就是不等待pause完成
            completePauseLocked(false);
            return false;

            } else {
            //launcher的最后onpause会走到这里来
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
            msg.obj = prev; prev.pauseTime = SystemClock.uptimeMillis();
            //设置pause的超时时间为500ms mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
            //返回ture,代表有响应的activity正在pausing,
            //故在章节5.2 resumeTopActivityInnerLocked运行完该函数后不久就返回了
            return true; }
            } else { //... 

           }

     7.  schedulePauseActivity(ActivityThread.java)

      1) schedulePauseActivity这个是通过handler(一直想吐槽这个hander也类名也太简洁了的点吧,一个”H”就搞定)在UI主线程里面做的事情
      2) schedulePauseActivity->PAUSE_ACTIVITY->handlePauseActivity->performPauseActivity->performPauseActivityIfNeeded
      3) 我们主要关注performPauseActivityIfNeeded当前activity暂停(这部分本章节讲解)、activityPaused通知AMS上一个activity暂停完成
           //ActivityThread给外部提供的接口,pause暂停是通过应用的主线程进行处理

             public final void schedulePauseActivity(.......) {

           int seq = getLifecycleSeq();

           //...

           //finished等于false,走的是PAUSE_ACTIVITY,userLeaving==true,dontReport==dontWait==false

             sendMessage( finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, token, (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0), configChanges, seq); }

           //handler传递,调用的是handlePauseActivity

            case PAUSE_ACTIVITY: {

          //...

          //进入pause的处理

          handlePauseActivity((IBinder) args.arg1, false, (args.argi1 & USER_LEAVING) != 0, args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); //... } break;

           //finished是false,userLeaving==true,dontReport==false

      8.  handlePauseActivity(......) {

          ActivityClientRecord r = mActivities.get(token);

          ...

          if (r != null) {

          //userLeaving一般都是true

          if (userLeaving) {

          //会进入此处,会调用activity.performUserLeaving,当离开用户可视的时候会调用

          performUserLeavingActivity(r); }

          //...

          //此处是pause上一个应用launcher,isPreHoneycomb是android3.0之前用的,此处是false

          performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");

          //dontReport一般没有设置都是false,故一般都是进入此处的

          if (!dontReport) {

          try {

          //通知AMS上一个应用完成pause了,这里接下去就会resume下一个应用(先启动进程),

          //下一章会讲到

          ActivityManagerNative.getDefault().activityPaused(token);

          } catch (RemoteException ex) {

          throw ex.rethrowFromSystemServer(); } } mSomeActivitiesChanged = true; }

          }

     9. performPauseActivity(.......) {

          //saveState是false,不跑这里

          if (!r.activity.mFinished && saveState) {

          callCallActivityOnSaveInstanceState(r); }

          //这里才是pause activity的地方

          performPauseActivityIfNeeded(r, reason);

          // 将当前pause的应用的OnActivityPausedListener暂停监听去除

          ArrayList<OnActivityPausedListener> listeners;

          synchronized (mOnPauseListeners) {

          listeners = mOnPauseListeners.remove(r.activity); }

          //...

          for (int i = 0; i < size; i++) {

          //此处是调用注册了该activity thread的监听onPaused的回调,

          //如NfcAdapter.java中的ActivityThread.currentActivityThread()                                       //.registerOnActivityPausedListener(activity,mForegroundDispatchListener);

          listeners.get(i).onPaused(r.activity); } //...

          }
      10. performPauseActivityIfNeeded(ActivityThread.java) :

        1) 通过代理类Instrumentation调用callActivityOnPause,其调用的是activity的performPause(分别会调用mFragments.dispatchPause、          activity的onPause,application的ActivityLifecycleCallback生命周期回调方法onActivityPaused)
        2) OnPause调用完成后会在event log中写入am_on_paused_called,代表activity的OnPause已经完成(如果你使用onpause有问题,可          以从am_pause_activity到am_on_paused_called之间所花费的时间做初步判断)
        3) 注意OnPause完成之后paused会赋值为true,代表当前是暂停状态

        private void performPauseActivityIfNeeded(.....) {

        if (r.paused) {

        //如果之前paused==true了就直接返回,activitythread创建设置成false,

        //oncreate将设置成ture,onresume将设置成false

        //上一个activity的上一个状态是onresume,正在pause,故此处是paused==false

        return;

        } try {

        //这里解释一下mCalled,这个值是用来判断是否有调用activity生命周期的函数

        r.activity.mCalled = false;

        //这就就是具体调用activity的performPause的地方

        //(包括mFragments.dispatchPause、activity的onPause,

        //application的ActivityLifecycleCallback生命周期回调方法onActivityPaused),

        //运行完之后mCalled会设置成true

        mInstrumentation.callActivityOnPause(r.activity);

        //写event log,am_on_paused_called,说明pause已经调用

        EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), r.activity.getComponentName().getClassName(), reason);

        //...

        //运行了之后设置标致位paused==true

        r.paused = true; }

 

https://blog.csdn.net/yun_hen/article/details/78590991  : 连接参考

 

   八、其他接口说明使用

     1. moveFocusableActivityStackToFrontLocked  (ActivityStackSupervisor.java)  :   将活动及其堆栈移到前面并设置为焦点,也是调用ActivityStack.java 中的movttoFront这个方法

     2. getProcessRecordLocked(AMS) :  这句话是判断是否已经运行这个进程

     

 

  Android中一般情况下有以下几种ActivityStack

    1:Home Stack,这个是Launcher所在的Stack。 其实还有一些系统界面也运行在这个Stack上,例如近期任务.SystemUI等
    2:FullScreen Stack,全屏的Activity所在的Stack。 但其实在分屏模式下,Id为1的Stack只占了半个屏幕。
    3:Freeform模式的Activity所在Stack
    4:Docked Stack 下文中我们将看到,在分屏模式下,屏幕有一半运行了一个固定的应用,这个就是这里的Docked Stack
    5:Pinned Stack 这个是画中画Activity所在的Stack

 

  十、ActivityThread 启动Application和Activity的流程

    1.  public void handleMessage(Message msg) {

      .......

      //getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord的成员变量packageInfo 。

      应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件

       r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo)

      case RELAUNCH_ACTIVITY:
      handleRelaunchActivityLocally((IBinder) msg.obj);
      break;

    }  

    2.  handleRelaunchActivityLocally 调用到 handleLaunchActivity这个函数

 

    3. handleLaunchActivity

     private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

      ...

      Activity a = performLaunchActivity(r, customIntent); //1              用来启动Activity

       if (a != null) {

        r.createdConfig = new Configuration(mConfiguration);

        reportSizeConfigurations(r);

        Bundle oldState = r.state;

        handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);           代码用来执行Activity的onResume方法,将Activity的状态置为Resume

        if (!r.activity.mFinished && r.startsNotResumed) {

          performPauseActivityIfNeeded(r, reason);

          if (r.isPreHoneycomb()) {

            r.state = oldState; }

           }

        } else {

          try {

           ActivityManagerNative.getDefault() .finishActivity(r.token, Activity.RESULT_CANCELED, null, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);         该Activity为null则会通知ActivityManager停止启动Activity

          } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } }

 

      4. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        ActivityInfo aInfo = r.activityInfo; //1

        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE); //2

        ComponentName component = r.intent.getComponent(); //3

        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); //4

        Application app = r.packageInfo.makeApplication(false, mInstrumentation); //5

        Context appContext = createBaseContextForActivity(r, activity); //6

        activity.attach(appContext, this, ........);  //7

        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); //8

        activity.performStart(); //9

        mActivities.put(r.token, r); //10

        

      注释1处用来获取ActivityInfo。
      注释2处获取APK文件的描述类LoadedApk。
      注释3处获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。
      注释4处根据ComponentName中存储的Activity类名,用类加载器通过反射来创建该Activity的实例。
      注释5处用来创建Application对象,makeApplication方法内部会调用Application的onCreate方法。该Application对象的唯一作用就是作为参数传递到Activity里,然后在Activity类中可以获得调用getApplication方法来获取Application对象。
      注释6处用来创建要启动Activity的上下文环境ContextImpl。
      注释7处调用Activity的attach方法初始化Activity,将ContextImpl对象注册到对应的Activity中,之后在Activity类中就可以使用Context的所有功能了。
      注释8处会调用Instrumentation的callActivityOnCreate方法来启动Activity。
      注释9处用来执行Activity的onStart方法。
      注释10处将启动的Activity加入到ActivityThread的成员变量mActivities中,其中mServices是ArrayMap类型。

    5. public Application makeApplication(.....) {

      if (mApplication != null) {   //1

          return mApplication;

       }

       ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);

       app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext);     //2

        instrumentation.callApplicationOnCreate(app);         //3

    }

    注释1判断当前应用是否是第一次创建Application对象,如果不是则直接返回Application对象,否则执行注释2创建第一个Application对象。目的是确保当前应用之创建了一个全局的Application对象。
    注释2调用Instrumentation的newApplication()方法创建Application。
    注释3调用Instrumentation的callApplicationOnCreate()。

 

  6.总体流程:

   1.Launcher通过Binder机制通知AMS启动一个Activity.
   2.AMS使Launcher栈最顶端Activity进入onPause状态.
   3.AMS通知Process使用Socket和Zygote进程通信,请求创建一个新进程.
   4.Zygote收到Socket请求,fork出一个进程,并调用ActivityThread#main().
   5.ActivityThread通过Binder通知AMS启动应用程序.
   6.AMS通知ActivityStackSupervisor真正的启动Activity.
   7.ActivityStackSupervisor通知ApplicationThread启动Activity.
   8.ApplicationThread发消息给ActivityThread,需要启动一个Activity.
   9.ActivityThread收到消息之后,通知LoadedApk创建Applicaition,并且调用其onCteate()方法.
   10.ActivityThread装载目标Activity类,并调用Activity#attach().
   11.ActivityThread通知Instrumentation调用Activity#onCreate().
   12.Instrumentation调用Activity#performCreate(),在Activity#performCreate()中调用自身onCreate()方法.

  7.Application和Activity#onCreate()方法调用顺序
      1.装载Activity
      2.装载Application
      3.Application#attach()
      4.Application#onCreate()
      5.Activity#attach()
      6.Activity#onCreate()

   
        

 

  十一、ActivityManagerService及其内部调度流程

   1. ActivityStack是专门实现对ActivityRecord的堆栈式管理而分离出来的一个模块, 所有对ActivityRecord的调度操作都在ActivityStack里进行,

    ArrayList列表记录了所有的ActivityRecord,ActivityStack所做的事情就是保证列表的第一个ActivityRecord(也就是“栈顶”)处于运行状态,

    并且排在列表后面的ActivityRecord的运行状态受到“栈顶”ActivityRecord的影响。

   2. ActivityRecord 的成员变量

    a. appToken  :  作为此ActivityRecord的唯一标识 

    b. TaskRecord  task : task标识了此ActivityRecord所属的Task, 在ActivityStack对ActivityRecord的位置调整中,如moveTaskToFront()、moveTaskToBack()等接口,

      会同时移动属于同一个Task的所有activity。 TaskRecord和ActivityRecord是一对多的关系,多个ActivityRecord可能指向同一个TaskRecord

    c. ProcessRecord app :  app标识了Client端的Activity所在的进程, ProcessRecord中的IApplicationThread可以直接操作Client端的ActivityThread

    d. 当进程运行起来之后,该进程的主线程会调用Client端的ActivityThread.main()函数,在main()函数中完成Looper的prepare(),并且生成ActivityThread对象,

     接着在ActivityThread.attach()中调用IActivityManager.attachApplication()回到AMS,在AMS中完成ProcessRecord和IApplicationThread对象的绑定

 

   3. 启动一个新的Activity的大致流程  

    1)  在Clien端请求打开新Activity之后,ActivityStack首先创建一个ActivityRecord并将其置于“栈顶”,此时ActivityRecord处于INITIALIZING状态。

    2)  接着调用resumeTopActivityLocked()。在resumeTopActivityLocked()中检查mResumedActivity是否为空,此时mResumedActivity指向A,所以肯定不为空。

    3)  调用startPausingLocked()暂停A。此时将mResumedActivity置空,mPausingActivity指向A, 并且将A的状态置为PAUSING。接着调用Activity A的Client端的schedulePauseActivity()将其暂停。

    4)  Client端的Activity 响应onPause()并且回调AMS的activityPaused()方法,将A的ActivityRecord的状态置为PAUSED,并把A添加到mStoppingActivities中。完成了A的暂停处理之后,会重新回到     第2)步。在第二步中,此时mResumedActivity为空,接下来的流程会最终调用到Activity B 的Client端的scheduleLaunchActivity()。此时Activity B的状态变为RESUMED。

    5)  ActivityB的Client端完成Activity的new和初始化并且响应onCreate()->onStart()->onResume(),然后回调AMS的activityIdle()方法告诉AMS已经运行完毕处于空闲状态。

    6)  activityIdleLocked()主要是完成经过“堆栈”经过调整之后的“善后”工作。如根据finishing状态完成挂起的销毁操作,处理mStoppingActivities中的挂起stop操作。经过第4)步,A已经在         mStoppingActivities中,所以接下来会调用A的Client端的scheduleStopActivity(booleanvisible),在Client端,根据接口参数visible判断,如果visible为false则响应onStop(),否则不响应。在       ActivityStack中,visible的值是通过从上到下的计算得出的。如果“栈顶”Activity为fullscreen,则处于“栈顶”底下的其他activity的visible全为false。这个计算过程在第4)步中会执行一次或多次。     在执行stop操作时,Activity A的状态从PAUSED变成STOPPING,再变成STOPPED。

    在第4)步的处理中,会继续调用resumeTopActivityLocked(),在resumeTopActivityLocked()中,会判断ActivityRecord中的ProcessRecord app是否为空,这里有两种情况:

    a) app不为空。

    这种情况的前提是,Activity B并不是新打开的而是在一直在后台,并且其进程没有由于内存回收而杀掉。在这种情况下,会直接调用scheduleResumeActivity(),Client端会进行响          应:onRestart()->onStart()->onResume()

    b) app为空

    app为空有三种情况,第一种是ActivityB之前一直在后台运行,由于内存不足被杀掉;第二种是Activity B是新打开的,并且不存在对应的进程;第三中情况是,Activity B 是新打开的,但是其进    程仍在运行中。在第一、二种情况中,AMS会启动新进程,并完成Activity B和新进程的ProcessRecord的绑定。

    在这三种情况中,最后都会调用scheduleLaunchActivity(),Client端会进响应:onCreate->onStart()->onResume()。

 

    https://blog.csdn.net/u010753159/article/details/52587591  留下来作为学习

 

 

 

单编译framework:

ln -sf out/combined-cepheus(机型).ninja build.ninja
cp prebuilts/build-tools/linux-x86/bin/ninja out/host/linux-x86/bin/
ninja framework -j8

 

 

 

 

 

 

 

 

 

 

 

       

posted on 2019-08-09 15:06  zhang11111wei  阅读(748)  评论(0编辑  收藏  举报

导航