zoukankan      html  css  js  c++  java
  • 进程启动学习

    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

           

  • 相关阅读:
    jquery 不支持$.browser
    js 双向绑定
    css3 省略号
    js生成txt文件
    Browser-sync
    Generator & yield write in sync way
    Charles
    缓动函数与动画
    让Safari使用Chrome的代理
    React 同构
  • 原文地址:https://www.cnblogs.com/liunx1109/p/11327270.html
Copyright © 2011-2022 走看看