Android7.1.1 ActivityManagerService关于Activity生命周期分析

前言

 对于Android开发者而言,最经常接触的就是四大组件了,Activity、Service、BroadcastReceiver、ContentProvider,其中Activity是我们使用频率最多的,这四个都是通过ActivityManagerService(下文简称AMS)进行管理的,本文就分析AndroidFramework中是如何管理Activity、以及如何创建Activity的。ActivityManagerService(以下简称AMS)启动Activity过程之前,要先弄明白几个重要的类及概念。

1、ActivityRecord介绍

 这个对应的就是应用开发过程AndroidManifest.xml以〈activity/>定义的各个Activity。这个表示的是Activity在AMS中的表示方式。下面介绍ActivityRecord一些重要的变量.

final class ActivityRecord {                                      
 /*表示AMS在创建ActivityRecord时候指定*/
 final ActivityManagerService service; // owner
 /*这个是和WindomMangerService通信的,該值会赋值给Activity中*/
 final IApplicationToken.Stub appToken; // window manager token
 /*这个描述是AndroidManifest.xml中定义activity相关信息*/
 final ActivityInfo info; // all about me
 /*这个描述是AndroidManifest.xml中定义application相关信息*/
 final ApplicationInfo appInfo; // information about activity's app    

 。。。。。。。。

 /*应用的包名*/
 final String packageName; // the packageimplementing intent's component
 final String processName; // process where this component wants torun
 /**Activity亲和性,这上简单的描述就是该Activity应属于是哪个Task*/
 final String taskAffinity; // as per ActivityInfo.taskAffinity
 。。。。。。。
 /**以下三个表示该Activity类型*/               
 static final int APPLICATION_ACTIVITY_TYPE= 0;
      static final int HOME_ACTIVITY_TYPE = 1;
      static final int RECENTS_ACTIVITY_TYPE = 2;
      int mActivityType;
 。。。。。。。
 /**Activity属于哪个Task*/
      TaskRecord task;        // the task this is in.
 /**通过startActivityForResult启动时,接收返回值的Activity*/
  ActivityRecord resultTo; // who startedthis entry, so will get our reply
      /**通过startActivityForResult启动时设置的requestCode*/
      final int requestCode;  // code given by requester (resultTo)
      。。。。。。。
      /*Activity所属的进程*/
     ProcessRecord app;      // ifnon-null, hosting application
 /*表示Activity的当前状态, INITIALIZING,RESUMED,PAUSING,PAUSED,STOPPING,STOPPED,FINISHING,DESTROYING,DESTROYED
 有这几种状态*/
 ActivityState state;    // current state we are in
    /*标记是否为Task的root Activity,比如每个应用有一个mainActivity,一般
    *情况下该main Activity即为对应Task的rootActivity*/
    boolean frontOfTask;    // isthis the root activity of its task?
    /*标记该ActivityRecord是否已经stoped*/
    boolean stopped;        // isactivity pause finished?
    /*标记ActivityRecord是否已经finishing,这在activity finish时置为true*/
    boolean finishing;      // activity in pending finish list?
    boolean deferRelaunchUntilPaused;   //relaunch of activity is being deferred until pause is
                                        //completed
    boolean visible;        // does this activity's window need tobe shown?
    boolean sleeping;       // have we told the activity to sleep?
    boolean nowVisible;     // is thisactivity's window visible?
    /*ActivityStack管理类*/
    final ActivityStackSupervisormStackSupervisor;

2、TaskRecord介绍

 这个是管理一个应用中ActivityRecord的容器,比如一个应用有很多的Activity,而这些Activity都是以Task栈方式进行管理,Task个人认为可以简单的认为一个应用,一个应用对应一个Task。下面说下TaskRecord一些重要的变量。

final class TaskRecord {
     /*该Task的id*/
    final int taskId;       // Unique identifier for this task.
    /*Task 亲合性,这个值可能会变化,这个值和ActivityRecord的taskAffinity对应*/
    String affinity;        // The affinity name for this task, ornull; may change identity.
    /*这个值标记Task中rootActivity的亲和性,和第一次启动该Task的root ActivityRecord中的taskAffinity对应,但是该值后续不会改变*/
    String rootAffinity;    // Initial base affinity, or null; does notchange from initial root.
    /**启动Task的Activity的intent*/
    Intent intent;          // The original intent that startedthe task.
    IntentaffinityIntent;  // Intent ofaffinity-moved activity that started this task.
    int effectiveUid;       // The current effective uid of theidentity of this task.
    ComponentNameorigActivity; // The non-alias activity component of the intent.
    ComponentNamerealActivity; // The actual activity component that started the task.
    int numFullscreen;      // Number of fullscreen activities.
    。。。。。。。。。

    /*这个即是用来保存一个Task中所有的 Activtiy,按栈的方式管理*/
    /** List of all activitiesin the task arranged in history order */
    finalArrayList<ActivityRecord> mActivities;
    /** Current stack
    *该Task所属的ActivityStack */
    ActivityStack stack;
    /** Takes on same set ofvalues as ActivityRecord.mActivityType
    *task类型和ActivityRecord的mActivityType对应*/
    int taskType;
    /** Indication of what torun next when task exits. Use ActivityRecord types.
     *ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task belowthis one in the
     * task stack. */
    private intmTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;

    /** If original intent didnot allow relinquishing task identity, save that information */
    booleanmNeverRelinquishIdentity = true;

    // Used in the unique casewhere we are clearing the task in order to reuse it. In that case we
    // do not want to deletethe stack when the task goes empty.
    private boolean mReuseTask= false;

    //这是截屏相关的
    private BitmapmLastThumbnail; // Last thumbnail captured for this item.
    private final FilemLastThumbnailFile; // File containing last thumbnail.

。。。。。。。。

    finalActivityManagerService mService;

    // Whether or not thistask covers the entire screen; by default tasks are fullscreen.
    boolean mFullscreen =true;

    // Bounds of the Task.null for fullscreen tasks
    //这是Task在屏幕显示区域
    Rect mBounds = null;
    。。。。。。。
}

3、ActivityStack介绍

 这个是管理TaskRecord的容器,也是系统中多窗口的概念读者参考

http://blog.csdn.net/guoqifa29/article/details/54863237,目前在Android7.1.2上面有以下几个,这些定义在android.app.ActivityManager.StackId中。

 

/** Homeactivity stack ID.这个包括Launcher的Activity以及recentsAPP */
 HOME_STACK_ID = FIRST_STATIC_STACK_ID;

/** ID ofstack where fullscreen activities are normally launched into. 这个即为我们应用启动的Activity所处于的ActivityStack*/
 FULLSCREEN_WORKSPACE_STACK_ID = 1;

 /** ID of stack where freeform/resizedactivities are normally launched into. */     FREEFORM_WORKSPACE_STACK_ID =FULLSCREEN_WORKSPACE_STACK_ID + 1;

 /** ID of stack that occupies a dedicatedregion of the screen. 这个是分屏应用所处于的ActivityStack*/
 DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID+ 1;

 /** ID of stack that always on top (alwaysvisible) when it exist.这个好像是画中画模式的Activity所处的   ActivityStack */
 PINNED_STACK_ID = DOCKED_STACK_ID + 1;

 /** Last static stack stack ID. */
 LAST_STATIC_STACK_ID = PINNED_STACK_ID;

 ActivityStack一些重要变量如下:

final classActivityStack {
         。。。。。。。
         /**Activity状态值*/
    enum ActivityState {
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED
    }
    。。。。。。。

    final ActivityManagerService mService;
    final WindowManagerService mWindowManager;
    private final RecentTasks mRecentTasks;

    /**
     * The back history of all previous (andpossibly still
     * running) activities.  It contains #TaskRecord objects.
     * 系统中的所有Task都保存在这里面,以栈的方式管理
     */
    private final ArrayList<TaskRecord>mTaskHistory = new ArrayList<>();

    /**
     * Activities that specify No History mustbe removed once the user navigates away from them.
     * If the device goes to sleep with such anactivity in the paused state then we save it here
     * and finish it later if another activityreplaces it on wakeup.
     */
    ActivityRecord mLastNoHistoryActivity =null;
    /**
     * Current activity that is resumed, ornull if there is none.
     * 这个表示当前ActivityStack处于running中的activity
     */

    ActivityRecord mResumedActivity = null;

/**
     * When we are in the process of pausing anactivity, before starting the
     * next one, this variable holds theactivity that is currently being paused.
     * 一般是mResumedActivity赋值
     * 这个表示此时正在pausing过程的activity
     */
    ActivityRecord mPausingActivity = null;

    /**
     * This is the last activity that we putinto the paused state.  This is
     * used to determine if we need to do anactivity transition while sleeping,
     * when we normally hold the top activitypaused.
     *这个表示此时正在paused过程的activity
     */
    ActivityRecord mLastPausedActivity = null;

    /**
     * This is the last activity that has beenstarted.  It is only used to
     * identify when multiple activities arestarted at once so that the user
     * can be warned they may not be in theactivity they think they are.
     */
    ActivityRecord mLastStartedActivity = null;

    final int mStackId;
     。。。。。。
    /**在每个ActivityStack中保存着一份所有的ActivityStack*/
    ArrayList<ActivityStack> mStacks;
    /** The attached Display's uniqueidentifier, or -1 if detached */
    int mDisplayId;

    /** Run all ActivityStacks through this
    *这个是管理ActivityStack的*/

    final ActivityStackSupervisor mStackSupervisor;

4、ActivityStackSupervisor介绍

         ActivityStackSupervisor这个是ActivityStack的管理类。以下几个比较重要的变量。读者看下。

/** The stack containing the launcherapp. Assumed to always be attached to
     * Display.DEFAULT_DISPLAY. */
    ActivityStack mHomeStack;

    /** The stack currently receiving input orlaunching the next activity. */
    ActivityStack mFocusedStack;

    /** If this is the same as mFocusedStackthen the activity on the top of the focused stack has
     * been resumed. If stacks are changingposition this will hold the old stack until the new
     * stack becomes resumed after which itwill be set to mFocusedStack. */
    private ActivityStack mLastFocusedStack;

 Android7.1.1系统存在以上几个ActivityStack,以栈的方式管理ActivityStack,而不同的应用处于不同的ActivityStack,每个ActivityStack以栈的方式管理多个TaskRecord,而每个TaskRecord又以栈的方式管理多个ActivityRecord。可以用图一表示。


                                                                               图一

5、ActivityThread介绍

         final ApplicationThread mAppThread =new ApplicationThread();

 这个是定义在ActivityThread中的变量,我们开发过程都一直说应用主线程,主线程即表示的是ActivityThread,一个应用它的主线程只有一个,应用中消息比如Acrivity的生命周期都是通过ActivityThread中的mAppThread这个进行分发。本文只是涉及ActivityManagerService其中Activity这一小部分,很多东西像WindowmanagerService的交互本文没有涉及。另外本文只是关注了ActivityStackID为HOME_STACK_ID的HomeStack和ActivityStack ID为FULLSCREEN_WORKSPACE_STACK_ID的FullscreenStack,像PINNED_STACK、FREEFORM_WORKSPACE_STACK、DOCKED_STACK这方面没有介绍。简单的认为只存在HomeStack和FullScreenStack两个ActivityStack这样有利于抓住主线。

         在分析AMS启动Activty之前,大家有必要先弄明白下Android的启动模式,这样有利于弄明白代码。启动模式和Task的介绍可以参考点击打开链接

 我们知道Android系统启动之后启动的第一个应用为Launcher那么我们以Launcher为例,结合代码分析AMS是如何启动一个Activity的,以下代码会忽略些和启动无关的代码,这样有利于我们抓住启动Activity这条主线。

         从AMS启动过程我们知道在AMS中是通过函数startHomeActivityLocked启动Launcher的,我们先来看下Launcher应用中AndroidManifest.xml中关于HomeActivity的Activity定义(请看图二),其中的launchMode、clearTaskOnLaunch、android.intent.category.HOME重点关注。

   

                                                        图 二

代码如下:

/*函数主要作用为获取HomeActivity(即应用AndroidManifest.xml中有设置android.intent.category.HOME,下文中HomeActivity即指该Activty)中的intent以及ActivityInfo*/
boolean startHomeActivityLocked(int userId, String reason) {
        if (mFactoryTest ==FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
  。。。。。。。。。
            return false;
        }
   //这边获取到的即为Launcher中AndroidManifest.xml有定义android.intent.category.HOME的Activity
        Intent intent = getHomeIntent();
        ActivityInfo aInfo =resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
        if (aInfo != null) {
            intent.setComponent(newComponentName(aInfo.applicationInfo.packageName, aInfo.name));
            // Don't do this if the home app iscurrently being
            // instrumented.
            aInfo = new ActivityInfo(aInfo);
            aInfo.applicationInfo =getAppInfoForUser(aInfo.applicationInfo, userId);
            ProcessRecord app =getProcessRecordLocked(aInfo.processName,
                    aInfo.applicationInfo.uid,true);
  /**因为是第一次启动Home 应用,所以对应的进程会null*/
            if (app == null || app.instrumentationClass== null) {
               intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
               mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
            }
        } else {
           Slog.wtf(TAG, "No home screen found for " + intent, newThrowable());
        }

        return true;

}

   接下去mActivityStarter.startHomeActivityLocked代码如下:

void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
      /**这是把HomeActivity所属的HomeStack移动到前台,
 *但是由于第一次启动HomeActivity还未创建,
 *其中所属的TaskRecord、以及ActivityRecrod为null
 */
       mSupervisor.moveHomeStackTaskToTop(ActivityRecord.HOME_ACTIVITY_TYPE,reason);
       startActivityLocked(null /*caller*/,intent, null /*ephemeralIntent*/,
                null /*resolvedType*/, aInfo,null /*rInfo*/, null /*voiceSession*/,
                null /*voiceInteractor*/, null/*resultTo*/, null /*resultWho*/,
                0 /*requestCode*/, 0/*callingPid*/, 0 /*callingUid*/, null /*callingPackage*/,
                0 /*realCallingPid*/, 0/*realCallingUid*/, 0 /*startFlags*/, null /*options*/,
                false /*ignoreTargetSecurity*/,false /*componentSpecified*/, null /*outActivity*/,
                null /*container*/, null/*inTask*/);

        if (mSupervisor.inResumeTopActivity) {
  。。。。。。
           mSupervisor.scheduleResumeTopActivities();
        }
    }

 说明以下的代码我会删除一些对于第一次启动HOME应用不必要的代码,读者可以自行看源码进行分析,大家千万要自己对着代码分析,因为本文这个涉及太多,另外一个作者能力有限有些内容会表述不清楚,会遗漏一些细节,读者对着代码看就会比较清晰了

 接下来部分是任何一个Activity的启动都会经历的流程。

 Activity的启动过程

         Activity启动过程可以概括以下几个步骤。

 1、前期准备工作

 2、计算Activity所属的Task、ActivityStack,及操作。

 3、paused之前Activity、resumed当前启动的Activity过程

 4、进程的创建

 5、Activity初始化流程

接下去我会按照这几个步骤,对照着源码进行下会析。

一、前期准备工作

 前期准备工作,其实就是初始化当前启动Activity相关的变量。我们进入ActivityStarter中的startActivityLocked(Android系统中任何Activity启动显示都会进入该函数)。代码如下:

final int startActivityLocked(
 IApplicationThreadcaller/*表示启动者所属的应用主线程,在ActivityThread中定义*/,
 Intent intent/*当前启动的Activity的Intent*/,
 IntentephemeralIntent,/*当前启动的Activity的Intent的复本*/
      String resolvedType,/*当前启动的Activity的resolvedType*/
 ActivityInfoaInfo,/*当前启动的Activity的ActivityInfo(PackageManger解析获得)*/
 ResolveInforInfo,/*当前启动的Activity的ResolveInfo */
 IVoiceInteractionSessionvoiceSession,/*暂时忽略为null&/
 IVoiceInteractorvoiceInteractor,/*暂时忽略为null*/
 IBinderresultTo, String resultWho,
 intrequestCode, /*通过startActivityForResult设置的值*/
 intcallingPid, int callingUid,
 String callingPackage,/*表示调用者即启动当前Activity所属的包名*/
      int realCallingPid, int realCallingUid,int startFlags,
      ActivityOptions options, booleanignoreTargetSecurity,
 boolean componentSpecified,
      ActivityRecord[]outActivity,
 ActivityStackSupervisor.ActivityContainercontainer, TaskRecord inTask) {

        int err = ActivityManager.START_SUCCESS;
        ProcessRecord callerApp = null;
 /*如果调用者不为null,查询是否已经创建了ProcessRecord,如果创建了,则
  *设置调用者的callingpid、callingUid*/
        if (caller != null) {
            callerApp =mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid =callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable tofind app for caller " + caller
                        + " (pid=" +callingPid + ") when starting: "
                        + intent.toString());
                err =ActivityManager.START_PERMISSION_DENIED;
            }
        }

        final int userId = aInfo != null ?UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;

        if (err ==ActivityManager.START_SUCCESS) {
            Slog.i(TAG, "START u" +userId + " {" + intent.toShortString(true, true, true, false)
                    + "} from uid " +callingUid
                    + " on display "+ (container == null ? (mSupervisor.mFocusedStack == null ?
                    Display.DEFAULT_DISPLAY :mSupervisor.mFocusedStack.mDisplayId) :
                    (container.mActivityDisplay== null ? Display.DEFAULT_DISPLAY :
                           container.mActivityDisplay.mDisplayId)));
        }

        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        /**这边判断的是,当前启动方式是以startActivityForResult启动的,
    *则保存调用者Activity在sourceRecord中,
    *如果启动时候设置了requestCode并且大于是0,那么接收
    *startActivityForResult返回值的Activity保存在resultRecord中。
    *其实读者可以看出来,调用者和接收返回者的Activity是相同的
    *举个例子:
    *Activity A通过startActivityForResult启动B,并且requestCode>0
    *那么此时sourceRecord和resultRecord都为A
    */

        if (resultTo != null) {
            sourceRecord =mSupervisor.isInAnyStackLocked(resultTo);
            if (DEBUG_RESULTS)Slog.v(TAG_RESULTS,
                    "Will send result to" + resultTo + " " + sourceRecord);
            if (sourceRecord != null) {
                if (requestCode >= 0&& !sourceRecord.finishing) {
                    resultRecord =sourceRecord;
                }
            }
        }

        final int launchFlags =intent.getFlags();
        /**
         *FLAG_ACTIVITY_FORWARD_RESULT这个FLAG作用,举个例子:
         *应用中存在有ActivityA,B,C,A以startActivityForResult方式启动了B,
         * 此时B设置了FLAG_ACTIVITY_FORWARD_RESULT启动了C,注意此时B启动C
         * 时requestCode不设置或者设置值要小于0,不然会报错。
         * 那么原来在A中接收返回值从B返回的,但这时A接收的返回值变成从C返回。
         */
        if ((launchFlags &Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
            // Transfer the result target fromthe source activity to the new
            // one being started, including anyfailures.
            if (requestCode >= 0) {
                ActivityOptions.abort(options);
                returnActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
            }

            resultRecord =sourceRecord.resultTo;
            if (resultRecord != null &&!resultRecord.isInStackLocked()) {
                resultRecord = null;
            }

            resultWho = sourceRecord.resultWho;
            requestCode =sourceRecord.requestCode;
            sourceRecord.resultTo = null;
            if (resultRecord != null) {
               resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
            }

            if (sourceRecord.launchedFromUid ==callingUid) {
                // The new activity is beinglaunched from the same uid as the previous
                // activity in the flow, and askingto forward its result back to the
                // previous.  In this case the activity is serving as atrampoline between
                // the two, so we also want toupdate its launchedFromPackage to be the
                // same as the previousactivity.  Note that this is safe, sincewe know
                // these two packages come fromthe same uid; the caller could just as
                // well have supplied that samepackage name itself.  This specifially
                // deals with the case of anintent picker/chooser being launched in the app
                // flow to redirect to anactivity picked by the user, where we want the final
                // activity to consider it tohave been launched by the previous app activity.
                callingPackage =sourceRecord.launchedFromPackage;
            }
        }
 。。。。。。。
        /**
         *创建需要启动的Activity对应的ActvityRecord
         *此时对应图一中AndroidManifest.xml中定义的HOME Activity
         */
        ActivityRecord r = newActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo,mService.mConfiguration, resultRecord, resultWho,
                requestCode,componentSpecified, voiceSession != null, mSupervisor, container,
                options, sourceRecord);

        if (outActivity != null) {
            outActivity[0] = r;
        }

。。。。。

     /**
 *这个是先启动延迟启动的Activity
 *对于本文启动Launcher时应该是为null的
 */
       doPendingActivityLaunchesLocked(false);
        try {
           /*windowmangerservice相关*/
           mService.mWindowManager.deferSurfaceLayout();
           err = startActivityUnchecked(r,sourceRecord, voiceSession, voiceInteractor, startFlags,
                    true, options, inTask);
        }finally {
           mService.mWindowManager.continueSurfaceLayout();
        }
        postStartActivityUncheckedProcessing(r,err, stack.mStackId, mSourceRecord, mTargetStack);
        return err;
    }

 接下来进入ActivityStarter中的startActivityUnchecked,在该函数中做的事情挺多的,也是最复杂的一部分。本文分析以HOME应用启动为主线,不涉及到HOME应用相关的代码我会先标注,一些其它的分析是在比较复杂的情况下,读者可以对应着启动模式对应着分析,这样会比较深刻明白。该函数主要包含以下几个步骤

 1、计算launchFlag

 2、计算调用者的ActivityStack

 3、检查是否存在复用的TaskRecord

 4、对于存在复用的TaskRecord则进行相应的ActivityStack、TaskRecord的移动(这个比较复杂).

 5、计算当前启动Activity所属的TaskRecord

 6、把当前启动的Activity放到所属TaskRecord的栈顶

 7、最后调用resumeFocusedStackTopActivityLocked创建正在启动的Activity、Paused当前resumed的Activity,以及resumed当前启动的Activity

 HOME应用的launchMode为singleTask、以及设置了clearTaskOnLaunch为true,结合这两点我们开始分析。

 startActivityUnchecked代码如下:

private intstartActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSessionvoiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume,ActivityOptions options,
  TaskRecord inTask){
 /*初始化一些值,读者自己看下*/
 setInitialState(r, options, inTask,doResume, startFlags,
 sourceRecord,voiceSession, voiceInteractor);
      /*计算当前启动Activity的是否要增加Intent.FLAG_ACTIVITY_NEW_TASK*/
      computeLaunchingTaskFlags();
      /*获取调用者的ActivityStack*/
  computeSourceStack();
      mIntent.setFlags(mLaunchFlags);
      /**
       *这边主要是判断当前启动的Activity是否存在可以利用的Task
       * 当启动模式launchMode为singleTask、singleInstance,或者启动时
       * Flag设置为FLAG_ACTIVITY_NEW_TASK并没设置FLAG_ACTIVITY_MULTIPLE_TASK
       * 并且当前启动的Activity不是以startActivityForResult启动的,
       * 满足以上情况才会寻找是否存在有复用的Task。
       * 匹配规则:
       * 1、对于启动模式为singleInstance,遍历所有ActivityStack和Task的堆栈中查找
       *是否存在以当前启动Activity相同的Activity。
       * 2、其它情况下,遍历所有ActivityStack和Task的堆栈,查找Task中intent变量                                                      * 是否当前启动Activity相匹配,如果不存在,则去匹配task的亲和性(即
   *在AndroidManifest中android:taskAffinity定义的。
       *对于本文介绍启动Launcher应用mResuedActivity为null
       */
       mReusedActivity =getReusableIntentActivity();
        。。。。。。。
}

         到这儿本章开头说的第一部分前期准备工作算是结束,我们总结下,前期准备工作主要做了什么:

         1、在ActivityStarter的startActivityLocked计算调用者的PID和UID,得到调用者的Activity sourceRecord、以及接收返回值的Activity resultRecord。创建当前启动的Activity对应的ActivityRecord,并且在ActivityRecord保存当前启动的Activity保存调用者、接收返回值的Activity,让Activity有迹可寻。

         2、在ActivityStarter的startActivityUnLocked中重置一些变量、对于调用者不为null情况下,得到调用者Activty所属的ActivityStack,接着判断对于当前启动的Activity,是否存在复用的Task,这部分主要是决定按何种方式启动Activity。

二、寻找Activity所属的Task、ActivityStack,及操作

 寻找Task、ActivityStack可以大致可以分为两种情况。

 1、  存在复用的Task情况。

 2、  不存在复用Task情况。

 接着第一章查找完复用Task之后的代码流程分析。

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSessionvoiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume,ActivityOptions options,
  TaskRecordinTask) {
 。。。。。。。。。
 final int preferredLaunchStackId = (mOptions != null) ?mOptions.getLaunchStackId() :                      ActivityManager.StackId.INVALID_STACK_ID;
       /**
       *表明当前的Task列表中存在有复用的Activity
       *可能为相同的Activity或者具有相同的affinity的task
       *如果是第一次启动某个应用或者从adb am中启动以及第一次启动Launcher
       *那么复用的TaskRecord为null
  *对于本文介绍启动Launcher应用中HOME Activity ,此时mResuedActivity为null
  *读者可以先忽略这分支代码
  *这边对应的是存在复用Task的情况
  */
        if (mReusedActivity != null) {
/*由于对于系统刚启动时启动HOMEActivity,还不存在有task,此时mResusedActivity为null所以可以先忽略这部分代码
*这部分代码主要是对于存在复用的TaskRecord则进行相应的ActivityStack、                                      *TaskRecord的移动,以及对于启动过程中设置相关的FLAG进行处理
*/
// When theflags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
// still needsto be a lock task mode violation since the task gets cleared out and
// the devicewould otherwise leave the locked task.

 if (mSupervisor.isLockTaskModeViolation(
 mReusedActivity.task,
 (mLaunchFlags &(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))

                      ==(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
               mSupervisor.showLockTaskToast();
                Slog.e(TAG,"startActivityUnchecked: Attempt to violate Lock Task Mode");
                returnSTART_RETURN_LOCK_TASK_MODE_VIOLATION;
            }

 //设置当前启动Activity的Task为复用的Task
 if (mStartActivity.task == null) {
                mStartActivity.task =mReusedActivity.task;
      }
      if (mReusedActivity.task.intent ==null) {
       // This task was started because ofmovement of the activity based on affinity...
       // Now that we are actually launchingit, we can assign the base intent.
                mReusedActivity.task.setIntent(mStartActivity);
       }
 // This codepath leads to delivering a new intent, we want to make sure we schedule it
 // as thefirst operation, in case the activity will be resumed as a result of later
 //operations.
 /*
 *这边处理启动时设置FLAG_ACTIVITY_CLEAR_TOP时,要清除复用Task中存在与当前启动
 *Activity相同的Activity之上的Activity
 *举个例子:比如复用Task1中存在有Activity A,B,C,D,此时正在启动的Activity B,那么C**和D也要finish,另外此时如果B *为标准启动模式,并且没有设置FLAG_ACTIVITY_SINGLE_TOP,那么B也会finish。具体的读者可以跟进
 *mReusedActivity.task.performClearTaskForReuseLocked看下。
 */
            if ((mLaunchFlags &FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || mLaunchSingleInstance ||mLaunchSingleTask) {
                // In this situation we want toremove all activities from the task up to the one
                // being started. In most casesthis means we are resetting the task to its initial
                // state.
                final ActivityRecord top =mReusedActivity.task.performClearTaskForReuseLocked(
                        mStartActivity,mLaunchFlags);
                if (top != null) {
                    if (top.frontOfTask) {
                        // Activity aliases maymean we use different intents for the top activity,
                        // so make sure thetask now has the identity of the new intent.
                       top.task.setIntent(mStartActivity);
                    }
                   ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);
                    if(shouldActivityBeBroughtToFront(mReusedActivity)) {
                       mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
                    }
                   //这边调用Activity中的onNewIntent
                   top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
                           mStartActivity.launchedFromPackage);
                }
            }
           sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
           //这边开始设置当前启动Activity所属的ActivityStack,如果需要要把Activity
           //所属的Task、ActivityStack移动到前台,见下面分析。
            mReusedActivity =setTargetStackAndMoveToFrontIfNeeded(mReusedActivity);

           //对于复用Task情况下START_FLAG_ONLY_IF_NEEDED这个FLAG只是resumed
           //具体这个Flag是啥意思不是很清楚,读者知道的可以告诉我下。
            if ((mStartFlags &START_FLAG_ONLY_IF_NEEDED) != 0) {
                // We don't need to start a newactivity, and the client said not to do anything
                // if that is the case, so thisis it!  And for paranoia, make sure wehave
                // correctly resumed the topactivity.
                resumeTargetStackIfNeeded();
                returnSTART_RETURN_INTENT_TO_CALLER;
            }

           setTaskFromIntentActivity(mReusedActivity);
            //如果不需要把当前启动的Activity增加到Task并且不存在复用Task
            //那么仅仅进行resumed过程。
            if (!mAddingToTask &&mReuseTask == null) {
                // We didn't doanything...  but it was needed (a.k.a.,client don't use that
                // intent!)  And for paranoia, make sure we have correctlyresumed the top activity.
                resumeTargetStackIfNeeded();
                return START_TASK_TO_FRONT;
            }
        }

         我们看下setTargetStackAndMoveToFrontIfNeeded这个函数里面是怎么操作Task和stack的。代码如下:

private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity){
        //targetStack设置成复用task所属的stack
        mTargetStack =intentActivity.task.stack;
        mTargetStack.mLastPausedActivity =null;
        // If the target task is not in thefront, then we need to bring it to the front...
        // except...  well, with SINGLE_TASK_LAUNCH it's notentirely clear. We'd like to have
        // the same behavior as if a newinstance was being started, which means not bringing it
        // to the front if the caller is notitself in the front.

        final ActivityStack focusStack =mSupervisor.getFocusedStack();
                   //这边是当前前台的Task和复用task不同,那么需要进行Task的移动

        if(shouldActivityBeBroughtToFront(intentActivity)) {
            if (mSourceRecord == null ||(mSourceStack.topActivity() != null &&
                   mSourceStack.topActivity().task == mSourceRecord.task)) {
                // We really do want to pushthis one into the user's face, right now.
                if (mLaunchTaskBehind&& mSourceRecord != null) {
                    intentActivity.setTaskToAffiliateWith(mSourceRecord.task);
                }

                mMovedOtherTask = true;
                // If the launch flags carryboth NEW_TASK and CLEAR_TASK, the task's activities
                // will be cleared soon by ActivityStarterin setTaskFromIntentActivity().
                // So no point resuming any ofthe activities here, it just wastes one extra
                // resuming, plus enter ANDexit transitions.
                // Here we only want to bringthe target stack forward. Transition will be applied
                // to the new activity that'sstarted after the old ones are gone.
                   final boolean willClearTask =
            (mLaunchFlags &(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
             == (FLAG_ACTIVITY_NEW_TASK |FLAG_ACTIVITY_CLEAR_TASK);
  /*如果FlagFLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK设置这两个时候,它会                                     *在接下来的代码中ActivityStarterin setTaskFromIntentActivity().清除该Task(后面会分析到
  *此处我们分析没有设置Flag的情况
  */
                if (!willClearTask) {
                    //计算当前启动的Activity所属的stack
                    final ActivityStacklaunchStack = getLaunchStack(
                            mStartActivity,mLaunchFlags, mStartActivity.task, mOptions);
                     //如果当前启动的Activity即为复用Task所属的ActivityStack
                    if (launchStack == null ||launchStack == mTargetStack) {
   // We onlywant to move to the front, if we aren't going to launch on a
   // differentstack. If we launch on a different stack, we will put the
   // task on topthere.

   //这边就是进行相关task和activityStack的移动了,这个只是在Task所属的ActivityStack中                                   //的移动不涉及把Task移动到其它ActivityStack,见下面分析。
                       mTargetStack.moveTaskToFrontLocked(
                               intentActivity.task, mNoAnimation, mOptions,
                                mStartActivity.appTimeTracker,"bringingFoundTaskToFront");
                        mMovedToFront = true;
                    } else if(launchStack.mStackId == DOCKED_STACK_ID
                            ||launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
    if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
                         /*If we want to launch adjacent and mTargetStack is not the computed
                          *launch stack - move task to top of computed stack.
      *这边是把复用的Task移动到其它的ActivityStack*/
    mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,launchStack.mStackId,
     ON_TOP, FORCE_FOCUS,"launchToSide",ANIMATE);
                        } else {
                         // TODO: Thisshould be reevaluated in MW v2.
     // We choose to move task to front instead oflaunching it adjacent
     // when specific stack was requestedexplicitly and it appeared to be
     // adjacent stack, butFLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
                     mTargetStack.moveTaskToFrontLocked(intentActivity.task, mNoAnimation,
                                    mOptions,mStartActivity.appTimeTracker,
                                   "bringToFrontInsteadOfAdjacentLaunch");
                        }
                        mMovedToFront = true;
                    }
                    mOptions = null;
                }
               updateTaskReturnToType(intentActivity.task, mLaunchFlags, focusStack);
            }
        }
        //这边表示如果不需要Task移动,移动targetStack到前台,见下文分析。
        if (!mMovedToFront &&mDoResume) {
            if (DEBUG_TASKS) Slog.d(TAG_TASKS,"Bring to front target: " + mTargetStack
                    + " from " +intentActivity);
           mTargetStack.moveToFront("intentActivityFound");
        }

        mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.task,INVALID_STACK_ID,
                mTargetStack.mStackId);

        // If the caller has requested that thetarget task be reset, then do so.
        if ((mLaunchFlags &FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
            returnmTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
        }

        return intentActivity;

}

 我们进入ActivitityStack中的moveTaskToFrontLocked分析Task如何在所属的Activity移动。代码如下:

 

final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation,
   ActivityOptions options,
        AppTimeTrackertimeTracker, String reason) {
        final int numTasks= mTaskHistory.size();
        final int index =mTaskHistory.indexOf(tr);
        if (numTasks == 0 ||index < 0)  {
            // nothing to do!
            if (noAnimation) {
               ActivityOptions.abort(options);
            } else {
               updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
            }
            return;
        }
         。。。。。。
        // Shift allactivities with this task up to the top
        // of the stack,keeping them in the same internal order.
        //这边就是把Task移动到ActivityStack的栈顶端
        //代码比较简单不列了
        insertTaskAtTop(tr,null);
  。。。。。。。。。
        // Set focus to the top running activity ofthis stack.
        //这时候stack的topActivity应该是上一步已经移到栈顶
        //复用的Task
        ActivityRecord r =topRunningActivityLocked();
        //更新AMS中的focusedActivity
        //这边会把当前Activity所属的Stack移到栈顶,
   //并且会更新ActivityStackSupervisor中的
        //mLastFocusedStack、mFocusedStack这两个变量
        mService.setFocusedActivityLocked(r, reason);

  。。。。。。。。
        //相应Activity状态的切换,这个后面章节会介绍
       mStackSupervisor.resumeFocusedStackTopActivityLocked();
 。。。。。。。。。。
    }

 经过上面的setTargetStackAndMoveToFrontIfNeeded这个函数之后,当前启动Activity复用的Task、以它所属的ActivityStack均已经移动到了栈顶。接着是调用setTaskFromIntentActivity,代码如下:

//这个主要是处理一些FLAG,

private void setTaskFromIntentActivity(ActivityRecordintentActivity) {

        if ((mLaunchFlags& (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                ==(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
// The caller has requested to completely replace any existing taskwith its new
// activity. Well that should not be too hard...
//设置了FLAG_ACTIVITY_CLEAR_TASK复用的Task会finish所有的Activity,并且重新
//更新复用Task信息的当前启动的Activity
           intentActivity.task.performClearTaskLocked();
           intentActivity.task.setIntent(mStartActivity);
            mReuseTask =intentActivity.task;
// When we clear the task - focus will be adjusted, which will bringanother task
// to top before we launch the activity we need. This will temporaryswap their
// mTaskToReturnTo values and we don't want to overwrite themaccidentally.
            mMovedOtherTask =true;
        } else if((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                ||mLaunchSingleInstance || mLaunchSingleTask) {
        ActivityRecord top =intentActivity.task.performClearTaskLocked(mStartActivity,
                   mLaunchFlags);
            if (top == null) {
     // A special case: we needto start the activity because it is not currently
     // running, and the callerhas asked to clear the current task to have this
     // activity at the top.
                mAddingToTask= true;
    // Now pretend like thisactivity is being started by the top of its task, so it
    // is put in the rightplace.
                mSourceRecord= intentActivity;
                finalTaskRecord task = mSourceRecord.task;
                if (task !=null && task.stack == null) {
                    // Target stack got cleared when we allactivities were removed above.
                    // Goahead and reset it.
                   mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
                           null /* bounds */, mLaunchFlags, mOptions);
                   mTargetStack.addTask(task,
                           !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
                }
            }
        } else if(mStartActivity.realActivity.equals(intentActivity.task.realActivity)) {
// In this case the top activity on the task is the same as the onebeing launched,
// so we take that as a request to bring the task to the foreground.If the top
// activity in the task is the root activity, deliver this newintent to it if it
// desires.
       if (((mLaunchFlags& FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
&&intentActivity.realActivity.equals(mStartActivity.realActivity)) {
                ActivityStack.logStartActivity(AM_NEW_INTENT,mStartActivity,
                       intentActivity.task);
                if(intentActivity.frontOfTask) {
                   intentActivity.task.setIntent(mStartActivity);
                }
              intentActivity.deliverNewIntentLocked(mCallingUid,mStartActivity.intent,
                       mStartActivity.launchedFromPackage);
            } else if(!intentActivity.task.isSameIntentFilter(mStartActivity)) {
         // In this case weare launching the root activity of the task, but with a
         // different intent.We should start a new instance on top.
                mAddingToTask= true;
                mSourceRecord= intentActivity;
            }

        } else if((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
            // In this case anactivity is being launched in to an existing task, without
            // resetting thattask. This is typically the situation of launching an activity
            // from anotification or shortcut. We want to place the new activity on top of the
            // current task.
            mAddingToTask =true;
            mSourceRecord =intentActivity;
        } else if(!intentActivity.task.rootWasReset) {
            // In this case weare launching into an existing task that has not yet been started
            // from its frontdoor. The current task has been brought to the front. Ideally,
            // we'd probablylike to place this new task at the bottom of its stack, but that's
            // a little hardto do with the current organization of the code so for now we'll
            // just drop it.
           intentActivity.task.setIntent(mStartActivity);
        }
    }

 接着上面分析完存在复用Task的操作之后,我们代码还得继续往下接着看代码:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSessionvoiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume,ActivityOptions options,
  TaskRecordinTask) {
                   。。。。。。。。。
        if (mReusedActivity != null){
                   。。。。。。。
   }       
        if (mStartActivity.packageName == null){
  /**异常处理*/
            if (mStartActivity.resultTo != null&& mStartActivity.resultTo.task.stack != null) {
                mStartActivity.resultTo.task.stack.sendActivityResultLocked(
                        -1,mStartActivity.resultTo, mStartActivity.resultWho,
                       mStartActivity.requestCode, Activity.RESULT_CANCELED, null);
            }
            ActivityOptions.abort(mOptions);
            returnActivityManager.START_CLASS_NOT_FOUND;
        }

        // If the activity being launched isthe same as the one currently at the top, then
        // we need to check if it should onlybe launched once.
        /**
   *对于系统刚启动HOME应用,此时FocusedStack即为HomeStack,
        * 这个在AMS初始化中ActivityStackSupervisor的setWindowManager初始化完成
   */
        final ActivityStack topStack =mSupervisor.mFocusedStack;
        /**对于本文启动Launcher中的HOME Activity这时候TOP为nulll*/
        final ActivityRecord top =topStack.topRunningNonDelayedActivityLocked(mNotTop);
        /*这个是对于Flag设置了SINGLE_TOP的和launchmode为singleTOp和singleTask时候,对于当前启动的Activity在     *TaskRecord栈顶时候,调用onNewIntent*/
        final boolean dontStart = top != null&& mStartActivity.resultTo == null
  &&top.realActivity.equals(mStartActivity.realActivity)
  && top.userId == mStartActivity.userId
  && top.app != null &&top.app.thread != null
  && ((mLaunchFlags &Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                || mLaunchSingleTop ||mLaunchSingleTask);

        if (dontStart) {
           ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,top.task);

            // For paranoia, make sure we havecorrectly resumed the top activity.
            topStack.mLastPausedActivity =null;

            if (mDoResume) {
               mSupervisor.resumeFocusedStackTopActivityLocked();
            }

            ActivityOptions.abort(mOptions);
            if ((mStartFlags &ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                // We don't need to start a newactivity, and the client said not to do
                // anything if that is thecase, so this is it!
                returnActivityManager.START_RETURN_INTENT_TO_CALLER;
            }

  top.deliverNewIntentLocked(mCallingUid,mStartActivity.intent,
    mStartActivity.launchedFromPackage);
            // Don't use mStartActivity.task toshow the toast. We're not starting a new activity
            // but reusing 'top'. Fields inmStartActivity may not be fully initialized.
            mSupervisor.handleNonResizableTaskIfNeeded(
                    top.task,preferredLaunchStackId, topStack.mStackId);
            returnActivityManager.START_DELIVERED_TO_TOP;
        }

        boolean newTask = false;
        final TaskRecord taskToAffiliate =(mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.task : null;

        // Should this be considered a newtask?
  /**
   *对于本文启动Launcher中的HOME Activity,需要创建TaskRecord,所以进入第
   *一个if流程
   *这这对应的是不存在复用Task的情况,需要重新创建一个Task
   */
        if (mStartActivity.resultTo == null&& mInTask == null && !mAddingToTask
   &&(mLaunchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;

            /*计算当前启动Activity所属的ActivityStack以及为它创建一个新的TaskRecord*/
            setTaskFromReuseOrCreateNewTask(taskToAffiliate);
            。。。。。。。。

}
}

        。。。。 。。。

进入setTaskFromResuseOrCreateNewTask函数,代码如下:

private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
                   /*这就是计算当前启动的Activity所属的ActivityStack
                   *对于本文介绍的启动Launcher中的HomeActivity,它对应
                   * 的ActivityStack为HomeStack
    */
 mTargetStack = computeStackFocus(mStartActivity,true, mLaunchBounds,
  mLaunchFlags, mOptions);

        if (mReuseTask == null) {
  /**
  *开始创建TaskRecord,并且把新的TaskRecord加入到targetStack的栈顶
  */
            final TaskRecord task =mTargetStack.createTaskRecord(
                   mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                    mNewTaskInfo != null ?mNewTaskInfo : mStartActivity.info,
                    mNewTaskIntent != null ?mNewTaskIntent : mIntent,
                    mVoiceSession,mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
            /*
  *设置正在启动的Activity所属的TaskRecord,
  *其实到这儿还没有把当前启动的Activity加入到该TaskRecord中,
  */
            mStartActivity.setTask(task,taskToAffiliate);
            if (mLaunchBounds != null) {
                final intstackId = mTargetStack.mStackId;
                if(ActivityManager.StackId.resizeStackWithLaunchBounds(stackId)) {
                    mService.resizeStack(
                           stackId, mLaunchBounds, true, !ActivityStackSupervisor.PRESERVE_WINDOWS,ActivityManagerService.ANIMATE, -1);
                } else {
                   mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
                }
            }
            if (DEBUG_TASKS)Slog.v(ActivityStackSupervisor.TAG_TASKS,
                    "Starting new activity" +
                            mStartActivity + " in new task" + mStartActivity.task);
        } else {
            mStartActivity.setTask(mReuseTask,taskToAffiliate);
        }
    }

 经过上一步正在启动的Activity所以对应的TaskRecord以及ActivityStack已经准备好,那么接下去ActivityStarter中未完成分析。

startActivityUnchecked(){
      ……
 setTaskFromReuseOrCreateNewTask(taskToAffiliate);
      if(mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
       Slog.e(TAG,"Attempted Lock Task Mode violation mStartActivity=" +mStartActivity);
            return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
 }
      if(!mMovedOtherTask) {
       // If stack idis specified in activity options, usually it means that activity is
       // launchednot from currently focused stack (e.g. from SysUI or from shell) - in
            // that casewe check the target stack.
            /*这是设置对应TaskRecord返回前一个ActivityStack的类型*/
               updateTaskReturnToType(mStartActivity.task, mLaunchFlags,
                       preferredLaunchStackId != ActivityManager.StackId.INVALID_STACK_ID ?mTargetStack : topStack);
            }
        }
 /*
 *这个if分支是不需要创建Task,并且调用者不为空
 *这个流程对应的也是存在复用Task的情况
 *对于本文是以启动Launcher中的HOME应用分析,这部分分支代码可以先忽略*/
 else if (mSourceRecord != null) {
       if(mSupervisor.isLockTaskModeViolation(mSourceRecord.task)) {
                Slog.e(TAG, "AttemptedLock Task Mode violation mStartActivity=" + mStartActivity);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
  /*
  *1、首先计算当前启动Activity所归属的ActivityStack
  *2、把该ActivityStack移动到前台
  *3、其中处理相关的Flag
  *4、设置当前启动的Activity的Task
  **/
            final int result =setTaskFromSourceRecord();
            if (result !=ActivityManager.START_SUCCESS) {
                return result;
            }
        } else if (mInTask != null) {
             /*对于本文是以启动HOME应用分析,这部分代码先忽略*/
            // The caller is asking that thenew activity be started in an explicit
            // task it has provided to us.
            if(mSupervisor.isLockTaskModeViolation(mInTask)) {
                Slog.e(TAG, "AttemptedLock Task Mode violation mStartActivity=" + mStartActivity);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
  /*这个从调用中指定的TaskRecord设定当前Activity所属的TaskRecord**/
            final int result =setTaskFromInTask();
            if (result !=ActivityManager.START_SUCCESS) {
                return result;
            }
        } else {
            // This not being started from anexisting activity, and not part of a new task...
            // just put it in the top task,though these days this case should never happen.
           setTaskToCurrentTopOrCreateNewTask();
        }
        mService.grantUriPermissionFromIntentLocked(mCallingUid,mStartActivity.packageName,
                mIntent,mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
        /*这个表示从任务列表中启动Activity,
    *对于本文是以启动HOME Activity分析不是从最近任务列表中启动*/
        if (mSourceRecord != null &&mSourceRecord.isRecentsActivity()) {
           mStartActivity.task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
        }
        mTargetStack.mLastPausedActivity =null;
       sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
       /*把当前启动的Activity加入TaskRecord以及绑定WindowManagerService*/
       mTargetStack.startActivityLocked(mStartActivity, newTask,mKeepCurTransition, mOptions);
      。。。。。。。。。。
}

 我们进入ActivityStack中的startActivityLocked中分析,代码如下:

final void startActivityLocked(ActivityRecord r, boolean newTask, booleankeepCurTransition, ActivityOptions    options) {
        TaskRecord rTask = r.task;
 /**
 * rTask即之前创建的TaskRecord,或者为复用的TaskRecord,
 *对于本文是以启动Launcher HOMEActivity它为setTaskFromReuseOrCreateNewTask* 这个创建的TaskRecord
 */
        final int taskId = rTask.taskId;
        // mLaunchTaskBehind tasks get placedat the back of the task stack.

        if (!r.mLaunchTaskBehind &&(taskForIdLocked(taskId) == null || newTask)) {
            // Last activity in task had beenremoved or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            insertTaskAtTop(rTask, r);/*插入新创建或复用的TaskRecord到栈顶*/
            mWindowManager.moveTaskToTop(taskId);/*同时在Windowmanager中也移动到栈顶*/
        }

        TaskRecord task = null;
        /*
    * 对于本文是以启动Launcher HOMEActivity,这时候是有创建
    * 一个新的TaskRecord,所以该分支不走
    */
        if (!newTask) {//这是表示存在复用的TaskRecord
            // If starting in an existing task,find where that is...
            boolean startIt = true;
            /**遍历TaskRecord
  *从这儿也可以得出TaskRecord在ActivityStack是以栈的方式管理的*/
            for (int taskNdx =mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
                task =mTaskHistory.get(taskNdx);
                if (task.getTopActivity() ==null) {
                    // All activities in taskare finishing.
                    continue;
                }
                /*在Task堆栈中找到了复用的Task*/
                if (task == r.task) {
                    // Here it is!  Now, if this is not yet visible to the
                    // user, then just add itwithout starting; it will
                    // get started when theuser navigates back to it.
                    if (!startIt) {
                        if(ActivityManagerDebugConfig.DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity" + r + " to task "
                                + task, newRuntimeException("here").fillInStackTrace());
   //把当前启动的Activity加入到复用的Task栈顶*/
   task.addActivityToTop(r);                       
   r.putInHistory();
   /*绑定到windowmanager中*/
                        addConfigOverride(r,task);
                        if (VALIDATE_TOKENS) {
                           validateAppTokensLocked();
                        }
                       ActivityOptions.abort(options);
                        return;
                    }
                    break;
                } else if (task.numFullscreen> 0) {
                    startIt = false;
                }
            }
        }
        task = r.task;
        /**当前启动的Activity加到所属Task栈顶中
    *对于本文是以启动Launcher HOMEActivity*/
        task.addActivityToTop(r);
        /*这个是标记Task中Activity堆栈的堆底Activity元素*/
        task.setFrontOfTask();
        r.putInHistory();
        /*如果当前ActivityStack不为 HomeStack,
   *或者该ActivityStack中activity个数不为0
   *对于本文是以启动Launcher HOMEActivity,所以该流程不走
   */
        if (!isHomeStack() || numActivities()> 0) {
            // We want to show the startingpreview window if we are
            // switching to a new task, or thenext activity's process is
            // not currently running.
            boolean showStartingIcon = newTask;
            ProcessRecord proc = r.app;
            if (proc == null) {
                proc =mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
            }
            /*对于刚启动HOME应用时,表示进程ProcessReocrd还为空*/
            if (proc == null || proc.thread ==null) {
                showStartingIcon = true;
            }
            if (DEBUG_TRANSITION)Slog.v(TAG_TRANSITION,
                    "Prepare opentransition: starting " + r);
             /*动画相关*/
            if ((r.intent.getFlags() &Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
               mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE,keepCurTransition);
                mNoAnimActivities.add(r);
            } else {
               mWindowManager.prepareAppTransition(newTask
                        ? r.mLaunchTaskBehind
                                ?AppTransition.TRANSIT_TASK_OPEN_BEHIND
                                :AppTransition.TRANSIT_TASK_OPEN
                        :AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
                mNoAnimActivities.remove(r);
            }
        /*当前启动的Activity绑定到WIndowManagerService当中*/
            addConfigOverride(r, task);
            boolean doShow = true;
            if (newTask) {
                // Even though this activity isstarting fresh, we still need
                // to reset it to make sure weapply affinities to move any
                // existing activities from other tasks into it.
                // If the caller has requestedthat the target task be
                // reset, then do so.
                if ((r.intent.getFlags() &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                    resetTaskIfNeededLocked(r,r);
                    doShow =topRunningNonDelayedActivityLocked(null) == r;
                }
            } else if (options != null&& options.getAnimationType()
                    ==ActivityOptions.ANIM_SCENE_TRANSITION) {
                doShow = false;
            }

            if (r.mLaunchTaskBehind) {
                // Don't do a starting windowfor mLaunchTaskBehind. More importantly make sure we
                // tell WindowManager that r is visibleeven though it is at the back of the stack.
               mWindowManager.setAppVisibility(r.appToken, true);
               ensureActivitiesVisibleLocked(null, 0,!ActivityStackSupervisor.PRESERVE_WINDOWS);
            } else if(SHOW_APP_STARTING_PREVIEW && doShow) {
                // Figure out if we aretransitioning from another activity that is
                // "has the same startingicon" as the next one.  This allowsthe
                // window manager to keep theprevious window it had previously
                // created, if it still hadone.
                ActivityRecord prev =r.task.topRunningActivityWithStartingWindowLocked();
                if (prev != null) {
                    // We don't want to reusethe previous starting preview if:
                    // (1) The current activityis in a different task.
                    if (prev.task != r.task) {
                        prev = null;
                    }
                    // (2) The current activityis already displayed.
                    else if (prev.nowVisible) {
                        prev = null;
                    }
                }
                r.showStartingWindow(prev,showStartingIcon);
            }
        } else {
            // If this is the first activity,don't do any fancy animations,
            // because there is nothing for itto animate on top of.
  /*当前启动的Activity绑定到WIndowManagerService当中*/
            addConfigOverride(r, task);
            ActivityOptions.abort(options);
            options = null;
        }

        if (VALIDATE_TOKENS) {
            validateAppTokensLocked();
        }

    }

 经过以上步骤,Task也创建了,也把当前启动的Activity加入到Task正确的位置,

ActivityStack也移动到了正确位置。那么剩下的可以分为两种情况

1、对于当前启动的Activity所属的进程已经创建情况,并且当前正在启动的Activity也已经创建过实例了,那么接下来调用resumed、 paused流程。

2、对于当前启动的Activity还没有实例化,他需要走实例化流程。

对于本文启动Launcher 他是需要先创建一个进程,所以接下去我们介绍,应用程序进程创建的过程。

三、Paused之前Activity、resumed当前启动的Activity过程

         这一部分其实对应的是Activity的生命周期,这个会在第五章节《Activity的生命周期》中介绍,目前先以系统刚跑起来,第一次启动Launcher 的HomeActivity作简单分析,这时候只是主要看到如何调用到Launcher的进程启动过程。因为经过前两的步骤,到这儿其实相关的Activity所属的Task 、ActivityStack都是移到了正确位置。

         我们继续ActivityStarter中的startActivityUnchecked未分析代码。

         

startActivityUnchecked()
                   。。。。。。。。
        if (mDoResume) {
            if (!mLaunchTaskBehind) {
          // TODO(b/26381750): Remove this codeafter verification that all the decision
          // points above moved targetStack tothe front which will also set the focus
          // activity.
  /*
  * 设置当前focused,因为经过以上几步,启动的activity已经转移到
  *栈顶端,这时候设置AMS当前focused的Activity,对于本文分析
  *启动Launcher HomeActivity,这时候focusedActivity即
  *为Launcher中的Home Activity
  *另外调用这个函数也会有ActivityStack、Task栈的移动,即调用各自栈把当
  *前正在启动的Activity所属的Task、ActivityStack移动到栈顶
  */
                mService.setFocusedActivityLocked(mStartActivity,"startedActivity");

            }
            /*这时应该为当前启动的Activity,对于本文即为图二表示的HomeActivity*/
  final ActivityRecord topTaskActivity =mStartActivity.task.topRunningActivityLocked();
             //当前HomeStack为focusable 所以该分支不走
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null&& topTaskActivity.mTaskOverlay
    && mStartActivity != topTaskActivity)) {
                。。。。。。
            } else {
                //最终调用该函数
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,mStartActivity,
                        mOptions);
            }
        } else {
           mTargetStack.addRecentActivityLocked(mStartActivity);
        }
       mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

       mSupervisor.handleNonResizableTaskIfNeeded(
                mStartActivity.task,preferredLaunchStackId, mTargetStack.mStackId);

        return ActivityManager.START_SUCCESS;

    }

 接下来分析一下ActivityStackSupervisor中的resumeFocusedStackTopActivityLocked,因为AMS对于Activity比较复杂的部分即为复用栈时候的处理以及最后这部分的resumed相关操作,这两部分读者最好以假定某种启动模式,并对应着代码进行分析,其实resumeFocusedStackTopActivityLocked这个对应的就是Activity生命周期

中的onPaused->onStopped->onDestory,这个我会在第五章节《Activity生命周期》介绍,这边先简单过一下。

boolean resumeFocusedStackTopActivityLocked(
 ActivityStack targetStack, ActivityRecord target,ActivityOptions targetOptions) {
 /**如果指定的ActivityStack存在,对于本文分析HOMEActivity启动,targetStack即为HomeStack*/
 if(targetStack != null && isFocusedStack(targetStack)) {
        //进入

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

 接着进入当前启动Activity所属ActivityStack中的resumeTopActivityUncheckedLocked,代码如下:

/**
     * Ensure that the top activity in thestack is resumed.
     *
     * @param prev The previously resumedactivity, for when in the process
     * of pausing; can be null to call fromelsewhere.
     * @param options Activity options.
     *
     * @return Returns true if something isbeing resumed, or false if
     * nothing happened.
     *
     * NOTE: It is not safe to call this methoddirectly as it can cause an activity in a
     *      non-focused stack to be resumed.
     *      Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked}to resume the
     *      right activity for the current system state.
     */
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options){
        。。。。。。
            //进入resumeTopActivityInnerLocked
            result =resumeTopActivityInnerLocked(prev, options);
        return result;

    }

 代码比较简单进入resumeTopActivityInnerLocked,这个函数代码比较长,大伙多看几遍。代码如下:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptionsoptions) {
         。。。。。。。
        // Find the first activity that is notfinishing.
        /*
   *首先获取当前ActivityStack中栈顶Activity                    
   *对于本文分析第一次启动Launcher 该next即为Launcher的HomeActivity
   */
        final ActivityRecord next =topRunningActivityLocked();

        //Remember how we'll process thispause/resume situation, and ensure
        // that the state is reset however wewind up proceeding.
   /*这个变量是表示是否回调Activity中的onUserLeaveHint和onUserInteraction函数*/
        final boolean userLeaving =mStackSupervisor.mUserLeaving;

        mStackSupervisor.mUserLeaving = false;

        final TaskRecord prevTask = prev !=null ? prev.task : null;
    if (next == null) {//这个表示如果当前ActivityStack不存在未完成的Activity那么会启动Launcher桌面
  final Stringreason = "noMoreActivities";

            final int returnTaskType = prevTask ==null || !prevTask.isOverHomeStack()
                    ?ActivityRecord.HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();

            if (!mFullscreen &&adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
                // Try to move focus to thenext visible stack with a running activity if this
                // stack is not covering theentire screen.
                returnmStackSupervisor.resumeFocusedStackTopActivityLocked(
                       mStackSupervisor.getFocusedStack(), prev, null);
            }

            // Let's just start up theLauncher...
            ActivityOptions.abort(options);
            if (DEBUG_STATES)Slog.d(TAG_STATES,
                    "resumeTopActivityLocked:No more activities go home");

            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            // Only resume home if on homedisplay

           return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType,prev, reason);
        }

 next.delayedResume= false;
      // If the top activity is the resumedone, nothing to do.
/*这个是如果当前ActivityStack的resumedActivity即为栈顶第一个未finish的Activity,那么表示已经resumed过了就不继续以下的处理*/
if(mResumedActivity == next && next.state == ActivityState.RESUMED&&
                   mStackSupervisor.allResumedActivitiesComplete()) {
            // Make sure we have executed anypending transitions, since there
            // should be nothing left to do atthis point.
           mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES)Slog.d(TAG_STATES,
                   "resumeTopActivityLocked: Top activity resumed " + next);
            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }

        final TaskRecord nextTask = next.task;
 /*这个是对上一个resumed的Activity的相关处理
 *针对本文第一次启动Launcher,HomeActivity即prev的finishing为false
 */
 if (prevTask!= null && prevTask.stack == this &&
                prevTask.isOverHomeStack()&& prev.finishing && prev.frontOfTask) {
            。。。。。。。。。。
            }
        }
 // If we aresleeping, and there is no resumed activity, and the top
        // activity is paused, well that is thestate we want.
        if(mService.isSleepingOrShuttingDownLocked()
  && mLastPausedActivity == next
  && mStackSupervisor.allPausedActivitiesComplete()) {

            // Make sure we have executed anypending transitions, since there
            // should be nothing left to do atthis point.
           mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                   "resumeTopActivityLocked: Going to sleep and all paused");

            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            return false;

        }
       。。。。。。。。

// The activity may be waiting for stop, but thatis no longer
        // appropriate for it.
       mStackSupervisor.mStoppingActivities.remove(next);
       mStackSupervisor.mGoingToSleepActivities.remove(next);
        next.sleeping = false;
        mStackSupervisor.mWaitingVisibleActivities.remove(next);
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,"Resuming " + next);
 
    // If we are currently pausing an activity,then don't do anything until that is done.
        if(!mStackSupervisor.allPausedActivitiesComplete()) {
            if (DEBUG_SWITCH || DEBUG_PAUSE ||DEBUG_STATES) Slog.v(TAG_PAUSE,
                   "resumeTopActivityLocked: Skip resume: some activitypausing.");

            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            return false;

        }

 mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
 // We need tostart pausing the current activity so the top one can be resumed...
   final boolean dontWaitForPause =(next.info.flags& FLAG_RESUME_WHILE_PAUSING) != 0;

 /**这个是pause掉不是FocusedStack的其它ActivityStack的栈顶activity*/
 *对于不是当前focusStack的并且存在有mResumedActivity不为null的都要paused
 */
  boolean pausing =mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
 /*
 *这个表示该ActivityStack已经存在resumedActivity
 *但是对于本文介绍启动Launcher HOMEActivity时其实到这儿HOME Activity还未实例化,*此时HomeStack中还不存在有 *Activity,这时候该mResumed为null,读者可以先跳过
 */
        if (mResumedActivity != null) {
             。。。。。。。。。
        }

 /*对于第一次启动HOME应用pausing为false
 *读者可以跳过
 */
        if (pausing) {
            。。。。。。。
            return true;
        } else if (
        //针对本文分析第一次启动Launcher HomeActivity,此时mResumedAcitivyt还
   //为null ,并且next.state状态还为INITIATION,这步可以先跳过
  mResumedActivity == next
  &&next.state == ActivityState.RESUMED
  &&mStackSupervisor.allResumedActivitiesComplete()){
。。。。。。。。。。
            return true;
        }

 // If the most recent activity was noHistory butwas only stopped rather
        // than stopped+finished because thedevice went to sleep, we need to make
        // sure to finish it as we're making anew activity topmost.
        /**
        *如果此时处于屏幕灭屏状态,并且当前Resumed的Activity设置了Intent.FLAG_ACTIVITY_NO_HISTORY
        *那么需要finish此Activity
        */
        if (mService.isSleepingLocked()&& mLastNoHistoryActivity != null &&
               !mLastNoHistoryActivity.finishing) {
            if (DEBUG_STATES)Slog.d(TAG_STATES,
                    "no-history finish of" + mLastNoHistoryActivity + " on new resume");
            requestFinishActivityLocked(mLastNoHistoryActivity.appToken,Activity.RESULT_CANCELED,
                    null,"resume-no-history", false);
            mLastNoHistoryActivity = null;
        }
 /*对于第一次启动HOME应用prev和next是相同
 *读者可以先跳过
 */
        if (prev != null && prev !=next) {
  。。。。。。
        }
        。。。。。。。
 
        // We are starting up the nextactivity, so tell the window manager
        // that the previous one will be hiddensoon.  This way it can know
        // to ignore it when computing thedesired screen orientation.
        boolean anim = true;
        if (mIsAnimationBoostEnabled == true&& mPerf == null) {
            mPerf = new BoostFramework();
        }

        if (prev != null) {//这边是准备相关的动画
  if (prev.finishing) {
                if (DEBUG_TRANSITION)Slog.v(TAG_TRANSITION,
                        "Prepare closetransition: prev=" + prev);
                if(mNoAnimActivities.contains(prev)) {
                    anim = false;
                   mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE,                                                                           false);
                } else {
                   mWindowManager.prepareAppTransition(prev.task == next.task
                            ?AppTransition.TRANSIT_ACTIVITY_CLOSE
                            :AppTransition.TRANSIT_TASK_CLOSE, false);
                }
               mWindowManager.setAppVisibility(prev.appToken, false);

            } else {
                if (DEBUG_TRANSITION)Slog.v(TAG_TRANSITION,
                        "Prepare opentransition: prev=" + prev);

                if(mNoAnimActivities.contains(next)) {
                    anim = false;
                   mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);

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

                }
            }
        } else {
  if(DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: noprevious");
            if (mNoAnimActivities.contains(next)){
                anim = false;
               mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
            } else {
               mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN,false);
            }
        }


   Bundler esumeAnimOptions = null;
        if (anim) {
            ActivityOptions opts =next.getOptionsForTargetActivityLocked();
            if (opts != null) {
                resumeAnimOptions =opts.toBundle();
            }
            next.applyOptionsLocked();
        } else {
            next.clearOptionsLocked();
        }
        ActivityStack lastStack =mStackSupervisor.getLastStack();

 /**
 *如果当前ActivityStack中,此时处于Task最顶端的Activity已经创建过了并且已经纳入相
 *应的进程中,那么进入该Activity的resumed过程。
 *举个例子:比如你已经通过Launcher启动了应用2中的Activity A,这时候按HOME键
 *返回到Launcher桌面,这时你又点击Launcher上应用2的图标,这时候就会调用onResumed
 *对于本文第一次启动Launcher HOME Activity next.app为null即还没有创建对应的进程
 *读者可以先跳过这一步
 */
        if (next.app != null &&next.app.thread != null) {
                       。。。。。。。。。
                return true;
            }
        } else {
            // Whoops, need to restart thisactivity!
            if (!next.hasBeenLaunched) {
   next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW){
   next.showStartingWindow(null, true);
                }
            }
  //对于本文第一次启动Launcher HOMEActivity或者第一次启动其它应用,最终调用这边开//始创建应用对应的进程
           mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
        return true;

}

         以上就是对于当前启动的Activity已经纳入到对应的进程时,paused之前的Activity以及resumed当前启动的Activity过程,这种情况下并没有Activity创建过程,因为他之前已经创建过了,这也符合应用开发过程中所说的Actiivity从后台到前台会调用Activity生命周期的onResumed函数。

 四、进程的创建

         针对本文paused之前Activity、resumed当前启动的Activity过程这一章节,主要是针对当前启动Activity已经创建的过程的分析,那么对于第一次启动过程,比如从Launcer桌面点击图标启动一个应用时,它是需要为它创建一个对应的进程的,本章节就介绍下一个应用对应的进程创建过程。

我们接着第三章节写的跟踪进入ActivityStackSupervisor中的startSpecificActivityLocked,代码如下:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, booleancheckConfig) {
        // Is this activity's applicationalready running?
 /*
 *根据Activity的processName(该值在应用AndroidManifest.xml中
 *android:process定义,如果未定义则默认为当前应用包名)在AMS查询当前启动*的Activity对应的进程是否存
 * 存在,对于本文第一次启动Launcher或者其它第一次启动应用时,app为null
  */
        ProcessRecord app =mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid,true);

 r.task.stack.setLaunchTime(r);
 /*对于第一次启动HOME应用或第一次启动其它应用,因为还没有创建对应的进程
 *所以app此时为null
 *读者可以无跳过这一步
 */
        if (app != null && app.thread!= null) {
  try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS)== 0
                        ||!"android".equals(r.info.packageName)) {
                    // Don't add this if it isa platform component that is marked
                    // to run in multipleprocesses, because this is actually
                    // part of the framework sodoesn't make sense to track as a
                    // separate apk in theprocess.
                   app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);

                }
               /*如果当前启动的Activity所属的进程已经存在,那么调用
                * 该函数只开始Activity初始化生命周期,而不需要再重新创建进程。
                */
                realStartActivityLocked(r, app,andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exceptionwhen starting activity "
                        +r.intent.getComponent().flattenToShortString(), e);
            }
        }

   //如果当前启动的Activity所属的进程还未创建,这边调用AMS为启动的Activity创建进程
        mService.startProcessLocked(r.processName,r.info.applicationInfo, true, 0,
                "activity",r.intent.getComponent(), false, false, true);

}

关于AMS中进程创建的我会忽略相关代码,抓住创建进程的主线,进入AMS中的startProcessLocked,最终调用到以下函数

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, intintentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, booleanisolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, StringentryPoint, String[] entryPointArgs, Runnable crashHandler) {
//相关代码各位读者可以自行分析
        long startTime =SystemClock.elapsedRealtime();
        ProcessRecord app;
         。。。。。。
//对于第一次启动应用此时app为null
        if (app != null && app.pid >0) {
         。。。。。。
        }
。。。。。。
if (app == null) {
            //这时候创建用来描述应用进程ProcessRecord
            app = newProcessRecordLocked(info,processName, isolated, isolatedUid);
。。。。。。
}
                   。。。。。。
startProcessLocked(
                app, hostingType,hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        checkTime(startTime,"startProcess: done starting proc!");
        return (app.pid != 0) ? app : null;
}

进入newProcessRecordLocked分析一下
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,boolean isolated, int isolatedUid) {
 String proc =customProcess != null ? customProcess : info.processName;
         BatteryStatsImpl stats =mBatteryStatsService.getActiveStatistics();
         final int userId =UserHandle.getUserId(info.uid);
         int uid = info.uid;
  。。。。。。。。
        }
 /**这时候开始创建ProcessRecord对象
 *创建的ProcessRecord会保存AMS中的mProcessNames和mPidsSelfLocked这两个
 *变量中,记住这两个变量,此时用来描述进程ProcessRecord所表示已经创建
 *OK,因为下面在创建Android主线程ActivityThread时
 *会用到此时创建的ProcessRecord
 */
final ProcessRecordr = new ProcessRecord(stats, info, proc, uid);
        if (!mBooted && !mBooting
   && userId == UserHandle.USER_SYSTEM
   && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
            r.persistent = true;
        }
        //保存创建的ProcessRecord到变量mProcessNames
        addProcessNameLocked(r);
    }

 分析完newProcessRecordLocked接着进入
 startProcessLocked(
                app, hostingType,hostingNameStr, abiOverride, entryPoint, entryPointArgs);
  。。。。。。
            boolean isActivityProcess =(entryPoint == null);

  //这个很重要,我们知道Android应用都存在一个应用主线ActivityThread即表示主线程
            if (entryPoint == null) entryPoint= "android.app.ActivityThread";

  //这边开始正式创建进程
            Process.ProcessStartResultstartResult = Process.start(entryPoint,
   app.processName,uid, uid, gids, debugFlags, mountExternal,
   app.info.targetSdkVersion,app.info.seinfo, requiredAbi, instructionSet, 
   app.info.dataDir,entryPointArgs);
  。。。。。。
  if (oldApp !=null && !app.isolated) {
                // Clean up anything relatingto this pid first
                Slog.w(TAG, "Reusing pid" + startResult.pid
                        + " while app isstill mapped to it");
               cleanUpApplicationRecordLocked(oldApp, false, false, -1,
                        true /*replacingPid*/);
            }

            synchronized (mPidsSelfLocked) {
                //把创建的ProcessRecord保存到mPidsSelfLocked变量中,
                this.mPidsSelfLocked.put(startResult.pid,app);

                if (isActivityProcess) {
                    Message msg =mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                    msg.obj = app;
                   mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                            ?PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
                }
            }
。。。。。。。。
}

         经过以上步骤,AMS中表示应用进程的ProcessRecord已经创建完毕,并且保存在了AMS中的mProcessNames、mPidsSelfLocked这两个变量当中。关于Process.start这块的大家可以上网看下关于Android中zygote如何创建进程的步骤,这边就不列了,本文的目的是梳理Activity的创建,最终进程创建OK之后他会调用ActivityThread中的main函数,这边说下ActivityThread中比较重要的变量。

/**这个mAppThread变量是和ProcessRecord以及AMS进行通信的*/

finalApplicationThread mAppThread = new ApplicationThread();

我们看下ActivityThread中的main函数代码如下:

public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"ActivityThreadMain");
        SamplingProfilerIntegration.start();

        // CloseGuard defaults to true and canbe quite spammy.  We
        // disable it here, but selectivelyenable it later (via
        // StrictMode) on debug builds, butusing DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event loggingin libcore
       EventLogger.setReporter(new EventLoggingReporter());

        // Make sure TrustedCertificateStorelooks in the right place for CA certificates
        final File configDir =Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

       Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = newActivityThread();
 //调用attach,记住传入的是参数为false
 thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler =thread.getHandler();
        }
。。。。。。

    }

 进入ActivityThread的attach函数

private void attach(boolean system) {
 ViewRootImpl.addFirstDrawHandler(newRunnable() {
  @Override
  public void run() {
   ensureJitEnabled();
            }
            });
           android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                   UserHandle.myUserId());
           RuntimeInit.setApplicationObject(mAppThread.asBinder());

            final IActivityManager mgr =ActivityManagerNative.getDefault();           try{
            =//注意传入的变量为IBinder类型的mAppThread
  mgr.attachApplication(mAppThread);
 } catch(RemoteException ex) {
  throwex.rethrowFromSystemServer();
 }
 BinderInternal.addGcWatcher(newRunnable() {
                @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)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG,"Dalvik max=" + (dalvikMax/1024)
                                + "total=" + (runtime.totalMemory()/1024)
                                + "used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged= false;
                        try {
                           mgr.releaseSomeActivities(mAppThread);
                        } catch(RemoteException e) {
                            throwe.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } else {//此时传入的参数为false以下分支先忽略,该分支是在AMS初始化
  //的时候进入该分支
  。。。。。。
 }
    }

这部分代码逻辑还是比较简单,读者自行看下,接着进入AMS中的attachApplication函数

 
@Override
    public final voidattachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid =Binder.getCallingPid();
            final long origId =Binder.clearCallingIdentity();
  attachApplicationLocked(thread, callingPid);
           Binder.restoreCallingIdentity(origId);
        }
    }

接着进入AMS的attachApplicationLocked,代码如下:

private finalboolean attachApplicationLocked(
  IApplicationThread thread,//该参数为ActivityThread中的mAppThread
            int pid) {

   // Find theapplication record that is being attached... either via
        // the pid if we are running inmultiple processes, or just pull the
        // next app record if we are emulatingprocess with anonymous threads.
        ProcessRecord app;

        if (pid != MY_PID && pid >=0) {
            synchronized (mPidsSelfLocked) {
  /**因为之前AMS中的startProcessLocked中已经创建应用对应的ProcessRecord,并且保存**在mPidsSelfLocked
  *忘记的可以看AMS中的startProcessLocked
  */
            app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }
   //这时候已经创建了,此时app不为null
        if (app == null) {
  Slog.w(TAG,"No pending application record for pid " + pid
                    + "(IApplicationThread " + thread + "); dropping process");
            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS,pid);

            if (pid > 0 && pid !=MY_PID) {
                Process.killProcessQuiet(pid);
                //TODO:killProcessGroup(app.info.uid, pid);
            } else {
                try {
                    thread.scheduleExit();
                } catch (Exception e) {
                    // Ignore exceptions.
                }
            }
            return false;
        }
。。。。。。
 /*
 *这边是设置ProcessRecord与ActivityThread进行通信的Ibinder对象,而ProcessRecord
 *在AMS中所以通过thread就建立了AMS和应用主线程ActivityThread的通信
 * thread即为ActivityThread中的mAppThread
 */
 app.makeActive(thread,mProcessStats);
。。。。。。
 /*
 *我们知道thread即为ActivityThread中的mAppThread所以这时候回调
 * ActivityThread中的bindApplication
 */
 thread.bindApplication(processName,appInfo, providers, app.instrumentationClass,
                    profilerInfo,
   app.instrumentationArguments,app.instrumentationWatcher,
                   app.instrumentationUiAutomationConnection, testMode,
                   mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode ||!normalMode, app.persistent,
                    newConfiguration(mConfiguration), app.compat,
                   getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            updateLruProcessLocked(app, false,null);
。。。。。。。

}       

这时候进入ActivityThread中的bindApplication代码如下:

public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo>providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo,Bundle instrumentationArgs,
                IInstrumentationWatcherinstrumentationWatcher,
                IUiAutomationConnectioninstrumentationUiConnection, int debugMode,
                boolean enableBinderTracking,boolean trackAllocation,
                boolean isRestrictedBackupMode,boolean persistent, Configuration config,
                CompatibilityInfo compatInfo,Map<String, IBinder> services, Bundle coreSettings) {
 
   if (services != null) {
                // Setup the service cache inthe ServiceManager
               ServiceManager.initServiceCache(services);
            }

            setCoreSettings(coreSettings);

            AppBindData data = newAppBindData();
            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.enableBinderTracking = enableBinderTracking;
            data.trackAllocation =trackAllocation;
            data.restrictedBackupMode =isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            sendMessage(H.BIND_APPLICATION,data);
        }

在这个函数中设置完相应的参数,通过Handler最终调用的函数是handleBindApplication

private voidhandleBindApplication(AppBindData data) {
        // Register the UI Thread as asensitive thread to the runtime.
 //这也是一堆代码,读者对着代码自行分析,这边先删除太占篇幅
         。。。。。。
 /*
         * Before spawning a new process, resetthe time zone to be the system time zone.
         * This needs to be done because thesystem time zone could have changed after the
         * the spawning of this process.Without doing this this process would have the incorrect
         * system time zone.
         */
        TimeZone.setDefault(null);
        /*
         * Set the LocaleList. This may changeonce we create the App Context.
         */
       LocaleList.setDefault(data.config.getLocales());
        synchronized (mResourcesManager) {
            /*
             * Update the system configurationsince its preloaded and might not
             * reflect configuration changes.The configuration object passed
             * in AppBindData can be safelyassumed to be up to date
             */

           mResourcesManager.applyConfigurationToResourcesLocked(data.config,data.compatInfo);
            mCurDefaultDisplayDpi =data.config.densityDpi;

            // This calls mResourcesManager sokeep it within the synchronized block.
           applyCompatConfiguration(mCurDefaultDisplayDpi);
        }
      /* 这边为进程创建了一个LoadApk对象并且保存在mPackages变量当中,
 * LoadApk主要用于应用的相关的resDir、libDir相关资源的东西,
 * 但是此时LoadApk的ClassLoader为null
 */
 data.info = getPackageInfoNoCheck(data.appInfo,data.compatInfo);
         。。。。。。。
        final boolean is24Hr ="24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
        DateFormat.set24HourTimePref(is24Hr);
 。。。。。。

        // Allow application-generated systracemessages if we're debuggable.
        // Instrumentation info affects theclass loader, so load it before
        // setting up the app context.

        final InstrumentationInfo ii;

        if (data.instrumentationName != null) {
            try {
                ii = newApplicationPackageManager(null, getPackageManager())
   .getInstrumentationInfo(data.instrumentationName,0);
            } catch(PackageManager.NameNotFoundException e) {
                throw new RuntimeException(
                        "Unable to findinstrumentation info for: " + data.instrumentationName);
            }

            mInstrumentationPackageName =ii.packageName;
            mInstrumentationAppDir =ii.sourceDir;
            mInstrumentationSplitAppDirs =ii.splitSourceDirs;
            mInstrumentationLibDir =getInstrumentationLibrary(data.appInfo, ii);
            mInstrumentedAppDir =data.info.getAppDir();
            mInstrumentedSplitAppDirs =data.info.getSplitAppDirs();
            mInstrumentedLibDir =data.info.getLibDir();
        } else {
            ii = null;
        }

 //这边开始创建Context大家在开发过程经常使用到的Context上下文了
        final ContextImpl appContext =ContextImpl.createAppContext(this, data.info);
   updateLocaleListFromAppContext(appContext,
        mResourcesManager.getConfiguration().getLocales());
 。。。。。。。
        // Continue loading instrumentation.
 /*
 * 1、创建Instrument
 *  Instrument这个大家在开发过程使用的比较少,这个有点儿类似Android应
 *的工具类,对于Activity所有的生命周期比如onCreate、onResume都是通过该
 *instrumetn进行分发调用
 * 这边说明下如果不是自定义的Instrument此时ii为null,对于自定义的Instrument
 * 是通过Context的startInstrumentation来启动一个进程,这时候ii就不会为null了
 */
        if (ii != null) {
  final ApplicationInfo instrApp = new ApplicationInfo();
            ii.copyTo(instrApp);
           instrApp.initForUser(UserHandle.myUserId());
            final LoadedApk pi =getPackageInfo(instrApp, data.compatInfo,
                   appContext.getClassLoader(), false, true, false);
            final ContextImpl instrContext =ContextImpl.createAppContext(this, pi)
            try {
                final ClassLoader cl =instrContext.getClassLoader()
                mInstrumentation =(Instrumentation)
                   cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                    "Unable to instantiateinstrumentation "
                    + data.instrumentationName+ ": " + e.toString(), e);
            }

  final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this,instrContext, appContext, component,
                   data.instrumentationWatcher,data.instrumentationUiAutomationConnection);
 
            if (mProfiler.profileFile != null&& !ii.handleProfiling
   &&mProfiler.profileFd == null) {
                mProfiler.handlingProfiling =true;
                final File file = newFile(mProfiler.profileFile);
                file.getParentFile().mkdirs();
               Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
            }
        } else {
            mInstrumentation = newInstrumentation();
        }

。。。。。。。ActivityClientRecord
        // Allow disk access during applicationand provider setup. This could
        // block processing ordered broadcasts,but later processing would
        // probably end up doing the same diskaccess.
        final StrictMode.ThreadPolicysavedPolicy = StrictMode.allowThreadDiskWrites();
        try {
            // If the app is being launched forfull backup or restore, bring it up in
            // a restricted environment withthe base application class.
  /**
  * 2、创建Application
  * 对于应用开发者可能会在应用中重载类Application,
  * 而这个Application一个应用只存在一个,这儿即创建Application
  */
            Application app =data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

            // don't bring up providers inrestricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                if(!ArrayUtils.isEmpty(data.providers)) {
   installContentProviders(app,data.providers);
                    // For process thatcontains content providers, we want to
                    // ensure that the JIT isenabled "at some point".
   mH.sendEmptyMessageDelayed(H.ENABLE_JIT,10*1000);
                }
            }

            // Do this after providers, sinceinstrumentation tests generally start their
            // test thread at this point, andwe don't want that racing.
            try {
               mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
                throw new RuntimeException(
                    "Exception thrown inonCreate() of "
                    + data.instrumentationName+ ": " + e.toString(), e);
            }

            try {
   //这儿就开始调用Application的onCreate函数
                  mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if(!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to createapplication " + app.getClass().getName()
                        + ": " +e.toString(), e);
                }
            }
        } finally {
           StrictMode.setThreadPolicy(savedPolicy);
        }
}

这边我们得分析一下,

Application app =data.info.makeApplication(data.restrictedBackupMode, null);因为这里边涉及很多重要的东西,主要为应用程序中的Application创建Context、LoadApk。我们进入LoadApk中的makeApplication代码如下:

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
       Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"makeApplication");

        Application app = null;
        String appClass =mApplicationInfo.className;
        //对于应用未重载Application时,默认为android.app.Application
        if (forceDefaultAppClass || (appClass== null)) {
            appClass ="android.app.Application";
        }
        try {
            java.lang.ClassLoader cl =getClassLoader();
            if(!mPackageName.equals("android")) {
               Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                       "initializeJavaContextClassLoader");
               initializeJavaContextClassLoader();
               Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
           /*
            * 创建ContextImple对象
            */
            ContextImpl appContext =ContextImpl.createAppContext(mActivityThread, this);
           /*
           *为当前启动的应用创建Application这部分作用
           *1、把上一步创建的appContext绑定到了ContextWrapper中mBase中
           *2、把当前LoadedApk绑定到应用ApplicationmLoadedApk
           *3、必须把创建的Application保存到LoadedApk当中
            */
            app =mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if(!mActivityThread.mInstrumentation.onException(app, e)) {
               Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiateapplication " + appClass
                    + ": " + e.toString(),e);
            }
        }

       mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
               instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if(!instrumentation.onException(app, e)) {
                   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to createapplication " + app.getClass().getName()
                        + ": " +e.toString(), e);
                }
            }
        }

        // Rewrite the R 'constants' for alllibrary apks.
        SparseArray<String>packageIdentifiers = getAssets(mActivityThread)
               .getAssignedPackageIdentifiers();
        final int N =packageIdentifiers.size();
        for (int i = 0; i < N; i++) {

            final int id =packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }

            rewriteRValues(getClassLoader(),packageIdentifiers.valueAt(i), id);
        }

       Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        return app;
    }

 经过以上几步,应用中所涉及到的Instrument、Application以有Application中的Context、LoadedApk相关的就已经都准备好了,此时还没有到Activity的生命周期当中,我们继续往下。。。。接下来返回继续AMS的attachApplicationLocked之后的流程。

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
。。。。。。
        // See if the top visible activity iswaiting to run in this process...
        if (normalMode) {
            try {
                if(mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
   Slog.wtf(TAG,"Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

。。。。。。
}

 进入ActivityStackSupervisor中的attachApplicationLocked代码如下

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
 final StringprocessName = app.processName;
        boolean didSomething = false;
        for (int displayNdx =mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks= mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() -1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack =stacks.get(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                ActivityRecord hr =stack.topRunningActivityLocked();
  /*因为在ActivityStarter中的startActivityUnchecked,即在本文第二章节<计算Activity所属的*Task、   *ActivityStack,及操作>中已经把要启动Activity所属的
  *ActivityStack以及TaskRecord移动到栈顶了,那么时候hr即为当前要启动的
  *Activity,本文是分析HOME应用,所以hr即为homeActivity
  */
  if (hr !=null) {
                    if (hr.app == null&& app.uid == hr.info.applicationInfo.uid
&&processName.equals(hr.processName)) {
                        try {
                            //这时候真正开始Activity的初始化生命周期
                            if(realStartActivityLocked(hr, app, true, true)) {
                                didSomething =true;
                            }
                        } catch(RemoteException e) {
                            Slog.w(TAG,"Exception in new application when starting activity "
                                  +hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
        if (!didSomething) {
  ensureActivitiesVisibleLocked(null,0, !PRESERVE_WINDOWS);
        }
        return didSomething;
}

这一章节主要流程是在AMS创建描述进程信息的ProcessRecord,并且保存到AMS中,

并且通过zygote进程来真正创建进程,此过程完成了应用主线程ActivityThread创建、应用Application的创建、Context的创建、LoadApk这些重要类的创建。但到这步Activity初始化流程其实还没有开始,这一部顶多完成了Acitivty初始化的准备工作。Activity生命周期介绍

         这一章节是所以Activity都会经历的生命周期。

我们知道activity的生命周期为onCreate->onStart->onResumed->running->onPaused->onStopped->onDestroy。这章节我们分析Activity生命周期分成两部分来介绍。

1、Activity创建过程的生命周期onCreate->onStart->onResumed

 这个过程在Activity初始化完成。 我们在第四章节介绍进程创建开头有提到ActivityStackSupervisor中的startSpecificActivityLocked这个函数中,如果当前启动的Activity所属的进程信息已经创建过了,那么直接调用realStartActivityLocked进入Activity初始化生命周期,对于第四章节介绍进程创建的最后对于新建的进程最终也会调用realStartActivityLocked进入Activity初始化生命周期。忘记的读者可以返回第四章节最后一部分回顾一下。

进入ActivityStackSupervisor中的realStartActivityLocked,代码如下:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, booleancheckConfig) throws RemoteException {
 。。。。。。
 //当前启动的Activity保存AMS中对Activity进程描述的ProcessRecord信息
        r.app = app;
 app.waitingToKill= null;
 r.launchCount++;
 r.lastLaunchTime= SystemClock.uptimeMillis();
      if (DEBUG_ALL) Slog.v(TAG,"Launching: " + r);
      int idx = app.activities.indexOf(r);
 //如果当前启动的Activty还不存在ProcessRecord中,则把它加到ProcessRecord中
       if (idx < 0) {
            app.activities.add(r);
        }
 。。。。。。
        final ActivityStack stack = task.stack;
 。。。。。。
            if (r.isHomeActivity()) {
                // Home process is the rootprocess of the task.
                mService.mHomeProcess =task.mActivities.get(0).app;
            }
 /**
 *我们之前在创建ProcessRecord时候,知道thread即为ActivityThread中的mAppThread,
 *这时我们进入ActivityThread中
 * 这步开始Activity初始化流程。。。
 */
 app.thread.scheduleLaunchActivity(
   new Intent(r.intent), r.appToken,
             System.identityHashCode(r),
   r.info, new Configuration(mService.mConfiguration),
             newConfiguration(task.mOverrideConfig),
 r.compat, r.launchedFromPackage,

 task.voiceInteractor, app.repProcState, r.icicle,r.persistentState, results,
            newIntents, !andResume,mService.isNextTransitionForward(), profilerInfo);
 。。。。。。
}

各位读者,这时候流程跑到这儿,马上就能够看到Activity的生命周期了,大家喝口水继续

进入ActivityThread中scheduleLaunchActivity,代码如下:

//we usetoken to identify this activity without having to send the
        // activity itself back to the activitymanager. (matters more with ipc)
        @Override
        public final voidscheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info,Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo,String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state,PersistableBundle persistentState,
                List<ResultInfo>pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, booleanisForward, ProfilerInfo profilerInfo) {

  updateProcessState(procState,false);
            ActivityClientRecord r = newActivityClientRecord();
  r.token =token;
  r.ident =ident;
  r.intent =intent;
  r.referrer =referrer;
  r.voiceInteractor= voiceInteractor;
  r.activityInfo= info;
  r.compatInfo =compatInfo;
  r.state =state;
  r.persistentState= persistentState;
  r.pendingResults= pendingResults;
  r.pendingIntents= pendingNewIntents;
  r.startsNotResumed= notResumed;
  r.isForward =isForward;
  r.profilerInfo= profilerInfo;
  r.overrideConfig= overrideConfig;
            updatePendingConfiguration(curConfig);
  sendMessage(H.LAUNCH_ACTIVITY,r);
}

通过Handler调用

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

获取LoadApk,Application在创建进程时候调用makeApplication已经创建,这时候不会再重新创建一个,而是直接采用之前创建的,然后调用handleLaunchActivity,代码如下:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, Stringreason) {
// If we aregetting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;
        if (r.profilerInfo != null) {
           mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }
        // Make sure we are running with themost recent config.
        handleConfigurationChanged(null, null); 
        // Initialize before creating theactivity
        WindowManagerGlobal.initialize();
//这儿就正式调用Activity的onCreate函数我们继续进入分析
        Activity a = performLaunchActivity(r,customIntent);
。。。。。
}

进入performLaunchActivity:代码如下

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
 ActivityInfoaInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo =getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                   Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component =r.intent.getComponent();
        if (component == null) {
            component =r.intent.resolveActivity(
               mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity !=null) {
            component = newComponentName(r.activityInfo.packageName,
                   r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
            java.lang.ClassLoader cl =r.packageInfo.getClassLoader();
//这儿先创建要启动的Activity的实例,本文分析为Home,所以此时创建的实例
//为HomeActivity,读者可以返回文章之前的图二
    activity =mInstrumentation.newActivity(
                    cl,component.getClassName(), r.intent);
           StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();

            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity,e)) {
                throw new RuntimeException(
                    "Unable to instantiateactivity " + component
                    + ": " +e.toString(), e);
            }
        }

        try {
  /*
  *这个在创建进程时候在调用ActivityThread调用makeApplication已经创
  *建过Application,所以此时只是返回之前创建的Application
  */
  Application app =r.packageInfo.makeApplication(false, mInstrumentation);
            if (activity != null) {
                 //为当前Activity 创建Context,实际上指向的是ContextImpl
                Context appContext = createBaseContextForActivity(r,activity);
      CharSequencetitle = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = newConfiguration(mCompatConfiguration);

                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }

                if (DEBUG_CONFIGURATION)Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name +" with config " + config);

                Window window = null;
                if (r.mPendingRemoveWindow !=null && r.mPreserveWindow) {
                    window =r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow =null;
                   r.mPendingRemoveWindowManager = null;
                }
  //这时候调用attach,这个函数很重要,列下几个重要的变量
  /**1、它把创建的Context回到了Activity中的context当中,这样Activity就获取到了*context
  *2、创建了PhoneWindow
  *3、创建了UI线程
  *4、得到了应用的主线程
  *5、mToken绑定到PhoneWindow。mToken即为ActivityRecord创建时的mAppToken
  *6、把创建进程时候创建的Application绑定到Activity
  *7、把ActivityRecord的Intent绑定Activity中的mIntent
  *8、把创建的Instrument绑定到Activity
  */
  activity.attach(appContext,this, getInstrumentation(), r.token,
                        r.ident, app, r.intent,r.activityInfo, title, r.parent,
                        r.embeddedID,r.lastNonConfigurationInstances, config,
                        r.referrer,r.voiceInteractor, window);
  if(customIntent != null) {
                    activity.mIntent =customIntent;
                }
                r.lastNonConfigurationInstances= null;
                activity.mStartedActivity = false;
                int theme =r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }
 
                activity.mCalled = false;
            //Activity实例创建完毕,也attach完之后,就开始调用onCreate
  //他是通过Instrument进行调用的,这在ActivityThread中handleBindApplication创建
  if(r.isPersistable()) {
                   mInstrumentation.callActivityOnCreate(activity, r.state,r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity,r.state);
                }

                if (!activity.mCalled) {
                    throw newSuperNotCalledException(
                        "Activity " +r.intent.getComponent().toShortString() +
                        " did not callthrough to super.onCreate()");
                }
   r.activity =activity;
                r.stopped = true;
                if (!r.activity.mFinished) {      
  ///开始调用onStart函数
  activity.performStart();

  r.stopped =false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null ||r.persistentState != null) {
                           mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
                        }
                    } else if (r.state != null){
                       mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
   activity.mCalled= false;
   ///调用函数onPasCreate
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity,r.state,
r.persistentState);
                    } else {
                       mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw newSuperNotCalledException(
                            "Activity" + r.intent.getComponent().toShortString() +
                            " did not callthrough to super.onPostCreate()");
                    }
                }
            }
  r.paused =true;
  mActivities.put(r.token,r);
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if(!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to startactivity " + component
                    + ": " +e.toString(), e);
            }
        }
        return activity;
    }



 经过以上步骤,当前启动的Activity实例初始化已经完成,每个Activity都要重新创建Context,通过attach初始化相关变量, context、PhoneWindow、UI线程、主线程、mToken绑定到PhoneWindow、Application绑定到Activity、Instrument绑定到Activity。我们应用开发经常碰到的Activity生命周期onCreate、onStart、onPostCreate已经调用,但是onResume还没有调用,我们继续handleLaunchActivity调用完performLaunchActivity之后的代码:

handleLaunchActivity{
 。。。。。。。。。
        if (a != null) {
 r.createdConfig= new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
//在这儿开始调用onResumed函数
 handleResumeActivity(r.token,false, r.isForward,
   !r.activity.mFinished&& !r.startsNotResumed, r.lastProcessedSeq, reason);
。。。。。。。。
    }

通过以上分析我们知道启动Activity生命周期onCreate->onStart->onResumed正式调用完毕。

继续之前ActivityStackSupervisor中的realStartActivityLocked调用完scheduleLaunchActivity之后的步骤。扫尾。。.

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, booleancheckConfig) throws RemoteException {
        if (andResume) {
            // As part of the process oflaunching, ActivityThread also performs
            // a resume.
//因为Activity已经调用完onResumed,所以这时候当前启动的Activity所属的ActivityStack中的mResumedActivity设置为当前启动的Activity,状态为RESUMED。
  stack.minimalResumeActivityLocked(r);
        } else {
.。。。。。。。。。
    }
。。。。。。。
}

2、Activity结束过程的生命周期onPasued->onStop->onDestory

 这个过程在Activity结束时候完成。到本小章节读者应该以假定此时已经启动了相关应用,并且假在在某种场景下,进

行Activity的切换,读者要记者一个Activity移动前台必然存在上一个Activity的paused过程,有些场景我还没有弄明白,如果有读者明白请指出来。

         我们对于第三章节简单分析resumeFocusedStackTopActivityLocked这边再继续深分析,弄明白Activity生命周期结束的部分。

         我们进入ActivityStackSupervisor中的resumeFocusedStackTopActivityLocked,看函数名字应该是resumed系统中focusedStack的处于栈顶的Activity。代码如下:

boolean resumeFocusedStackTopActivityLocked(
 ActivityStack targetStack,//目标ActivityStack,可为null
 ActivityRecord target, //上一个resumed的activity,可为null
 ActivityOptions targetOptions) {
      /*
      *对于指定的tagetStack存在,并且为Focused的stack,那么进入
      *指定的targetStack进行resume操作。
      */
 if (targetStack != null &&isFocusedStack(targetStack)) {
            returntargetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
 /*
 *指定的ActivityStack不存在则获取当前Focused的ActivityStack
 *获取focusedStack的处于顶端的Activity,并且此时activity的状态
 *不为RESUMED
 */
        final ActivityRecord r =mFocusedStack.topRunningActivityLocked();
   if (r == null || r.state !=ActivityStack.ActivityState.RESUMED) {
           mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
   return false;
    }

接着进入对应的ActivityStack中的resumeTopActivityUncheckedLocked,代码如下:

/**
     * Ensure that the top activity in thestack is resumed.
     *
     * @param prev The previously resumedactivity, for when in the process
     * of pausing; can be null to call fromelsewhere.
     * @param options Activity options.
     *
     * @return Returns true if something isbeing resumed, or false if
     * nothing happened.
     *
     * NOTE: It is not safe to call this methoddirectly as it can cause an activity in a
     *      non-focused stack to be resumed.
     *      Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked}to resume the
     *      right activity for the current system state.
     */
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev,ActivityOptions options) {
         //当前系统正在处于resumeTopActivity过程则返回
        if(mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
           mStackSupervisor.inResumeTopActivity = true;
       if (mService.mLockScreenShown ==ActivityManagerService.LOCK_SCREEN_LEAVING) {
            mService.mLockScreenShown =ActivityManagerService.LOCK_SCREEN_HIDDEN;
               mService.updateSleepIfNeededLocked();
       }
            result =resumeTopActivityInnerLocked(prev, options);
        } finally {
           mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

 代码比较简单进入resumeTopActivityInnerLocked,这个函数代码比较长,大伙多看几遍。代码如下:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptionsoptions) {
         。。。。。。。
        ActivityRecord parent =mActivityContainer.mParentActivity;
        if ((parent != null &&parent.state != ActivityState.RESUMED) ||
               !mActivityContainer.isAttachedLocked()) {
            // Do not resume this stack if itsparent is not resumed.
            // TODO: If in a loo, make surethat parent stack resumeTopActivity is called 1st.
            return false;
        }
       mStackSupervisor.cancelInitializingActivities();

        // Find the first activity that is notfinishing.
        /*
   *首先获取当前ActivityStack中栈顶Activity,这个即为我们
   *要resumed的Activity
   */
        final ActivityRecord next =topRunningActivityLocked();
        //Remember how we'll process thispause/resume situation, and ensure
        // that the state is reset however we wind upproceeding.
   /*这个变量是表示是否回调Activity中的onUserLeaveHint和onUserInteraction函数*/
        final boolean userLeaving =mStackSupervisor.mUserLeaving;
        mStackSupervisor.mUserLeaving = false;

        final TaskRecord prevTask = prev !=null ? prev.task : null;
        if (next == null) {//这个表示如果当前ActivityStack不存在未完成的Activity那么会启动Launcher桌面
  final Stringreason = "noMoreActivities";
            final int returnTaskType = prevTask== null || !prevTask.isOverHomeStack()
                    ?ActivityRecord.HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
            if (!mFullscreen &&adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
                // Try to move focus to thenext visible stack with a running activity if this
                // stack is not covering theentire screen.
                returnmStackSupervisor.resumeFocusedStackTopActivityLocked(
                       mStackSupervisor.getFocusedStack(), prev, null);
            }

            // Let's just start up theLauncher...
            ActivityOptions.abort(options);

            if (DEBUG_STATES)Slog.d(TAG_STATES,
                   "resumeTopActivityLocked: No more activities go home");

            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            // Only resume home if on homedisplay
           return isOnHomeDisplay() &&
          mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
        }

next.delayedResume= false;
// If the topactivity is the resumed one, nothing to do.
/*这个是如果当前ActivityStack的resumedActivity即为栈顶Activity,那么表示已经resumed过了就不继续以下的处理*/

if(mResumedActivity == next && next.state == ActivityState.RESUMED&&
                   mStackSupervisor.allResumedActivitiesComplete()) {
            // Make sure we have executed anypending transitions, since there
            // should be nothing left to do atthis point.
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES)Slog.d(TAG_STATES,
                   "resumeTopActivityLocked: Top activity resumed " + next);
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
        final TaskRecord nextTask = next.task;
/*
*这个是对上一个resumed的Activity的相关处理
*针对这个,本人不是很不清楚表示的场景
*/
if (prevTask!= null && prevTask.stack == this &&
                prevTask.isOverHomeStack()&& prev.finishing && prev.frontOfTask) {
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            if (prevTask == nextTask) {
                prevTask.setFrontOfTask();
            } else if (prevTask != topTask()) {
                // This task is going away butit was supposed to return to the home stack.
                // Now the task above it has toreturn to the home task instead.
                final int taskNdx = mTaskHistory.indexOf(prevTask)+ 1;
               mTaskHistory.get(taskNdx).setTaskToReturnTo(ActivityRecord.HOME_ACTIVITY_TYPE);
            } else if (!isOnHomeDisplay()) {
                return false;
            } else if (!isHomeStack()){
                if (DEBUG_STATES)Slog.d(TAG_STATES,
                       "resumeTopActivityLocked: Launching home next");
         final int returnTaskType = prevTask ==null || !prevTask.isOverHomeStack() ?
    ActivityRecord.HOME_ACTIVITY_TYPE:prevTask.getTaskToReturnTo();
                return isOnHomeDisplay()&&
                       mStackSupervisor.resumeHomeStackTask(returnTaskType, prev,"prevFinished");
            }
        }
// If we are sleeping, and there is no resumedactivity, and the top
        // activity is paused, well that is thestate we want.
        if(mService.isSleepingOrShuttingDownLocked()
  && mLastPausedActivity == next
  && mStackSupervisor.allPausedActivitiesComplete()) {
            // Make sure we have executed anypending transitions, since there
            // should be nothing left to do atthis point.
           mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                   "resumeTopActivityLocked: Going to sleep and all paused");
            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }

        // Make sure that the user who ownsthis activity is started.  If not,
        // we will just leave it as is becausesomeone should be bringing
        // another user's activities to the topof the stack.
   //这个是多用户相关
        if (!mService.mUserController.hasStartedUserState(next.userId)){
            Slog.w(TAG, "Skipping resumeof top activity " + next
                    + ": user " +next.userId + " is stopped");
            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
 
 // Theactivity may be waiting for stop, but that is no longer
      // apprpriate for it.
       mStackSupervisor.mStoppingActivities.remove(next);
       mStackSupervisor.mGoingToSleepActivities.remove(next);
        next.sleeping = false;
       mStackSupervisor.mWaitingVisibleActivities.remove(next);

        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,"Resuming " + next);

        // If we are currently pausing anactivity, then don't do anything until that is done.
        if(!mStackSupervisor.allPausedActivitiesComplete()) {
            if (DEBUG_SWITCH || DEBUG_PAUSE ||DEBUG_STATES) Slog.v(TAG_PAUSE,
                   "resumeTopActivityLocked: Skip resume: some activitypausing.");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
 mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
// We need tostart pausing the current activity so the top one can be resumed...
  final boolean dontWaitForPause =(next.info.flags& FLAG_RESUME_WHILE_PAUSING) != 0;
/*
*这个是pause掉不是FocusedStack的其它ActivityStack的栈顶activity*/
*对于不是当前focusStack的并且存在有mResumedActivity不为null的都要paused
*举个例子:如果当前处于FULLSCREEN_WORKSPACE_STACK(应用处于的Stack)
*这时候按HOME键切换到Launcher桌面,因为Launcher是处于HOME_STACK,
*那么时候需要把FULLSCREEN_STACK中的resumed 状态的Activity进行pausing过程
*/
 boolean pausing =mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
/*
*这个表示当前ActivityStack已经存在resumedActivity,也进行pausing过程。
*/
        if (mResumedActivity != null) {
            pausing |=startPausingLocked(userLeaving, false, next, dontWaitForPause);
        }

         我们分析关于Activity如何进行Pausing操作。进入startPausingLocked函数,

/**
     * Start pausing the currently resumedactivity.  It is an error to call this ifthere
     * is already an activity being paused orthere is no resumed activity.
     *
 *@param userLeaving True if this should result in an onUserLeavingto the current activity.
     * @param uiSleeping True if this ishappening with the user interface going to sleep (the screen turning off).
     * @param resuming The activity we arecurrently trying to resume or null
 * if this is not being called as part of resuming the top activity,so we
 * shouldn't try to instigate a resume here if not null.
     * @param dontWait True if the caller doesnot want to wait for the pause to
 * complete.  If set to true,we will immediately complete the pause
 * here before returning.
 * @return Returns true if an activity now is in thePAUSING state, and we are
 * waiting for it to tell us when it is done.
     */
//函数的注释大伙可以看下,其中参数dontWait表示如何Activity如果有设置
//android:resumeWhilePausing="true"那么会马上进行PAUSED
    final boolean startPausingLocked(booleanuserLeaving, boolean uiSleeping,
            ActivityRecord resuming,
  boolean dontWait

) {
      //这个表示ActivityStack中的已经进行过了pausing操作,那么接下去直接finish操作
        if (mPausingActivity != null) {
            Slog.wtf(TAG, "Going to pausewhen pause is already pending for " + mPausingActivity
                    + " state=" +mPausingActivity.state);
            if (!mService.isSleepingLocked()) {
                // Avoid recursion among checkfor sleep and complete pause during sleeping.
                // Because activity will bepaused immediately after resume, just let pause
                // be completed by the order ofactivity paused from clients.
                completePauseLocked(false,resuming);
            }
        }
 
        ActivityRecord prev = mResumedActivity;
        //表示当前ActivityStack还没有resumed 过Activity,直接返回
        if (prev == null) {
            if (resuming == null) {
                Slog.wtf(TAG, "Trying topause when nothing is resumed");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }
       /*
 *这边就是转换过程中一些Activity状态的记录过程,大致这样
      *mResumedActivity->mPausingActivity
      *mResumedActivity->mLastPausedActivity
      */
        mResumedActivity = null;
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        mLastNoHistoryActivity =(prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags &ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
                   //这边该ActivityStack中的resumedActivity状态变成了PAUSING状态
        prev.state = ActivityState.PAUSING;
  。。。。。。
        final ActivityRecord next =mStackSupervisor.topRunningActivityLocked();
        if (mService.mHasRecents
   &&(next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
            //这是标记该ResumedActivity是否需要截屏
            prev.mUpdateTaskThumbnailWhenHidden= true;
        }
  。。。。。。。
           //这儿就是该ActivityStack的resumedActivity的调用onPause函数
           *注意此时prev.state值为 ActivityState.PAUSING
        if (prev.app != null &&prev.app.thread != null) {
            try {
               EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId,System.identityHashCode(prev),
                        prev.shortComponentName);
                mService.updateUsageStats(prev,false);
            /*调用Activity的onPaused,这个流程不分析了,读者可以自行分析
            *如果dontWait为false(即android:resumeWhilePausing为false时候)
  *它调用ActivityThread的schedulePauseActivity之后,
  *ActivityThread会通过AMS会回调该ActivityStack的activityPausedLocked*函数并且会调用completePauseLocked这  *个函数下面还会涉及,下面再分*析,在这个函数里面会把该activity的状态prev.state修改成PAUSED,
            */
               prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving,prev.configChangeFlags, dontWait);
            } catch (Exception e) {
                // Ignore exception, if processdied other code will cleanup.
                Slog.w(TAG, "Exceptionthrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }

        // If we are not going to sleep, we wantto ensure the device is
        // awake until the next activity isstarted.
        if (!uiSleeping &&!mService.isSleepingOrShuttingDownLocked()) {
           mStackSupervisor.acquireLaunchWakelock();
        }
        /如果上步在调用onPaush没有出错,或者resumed对应的进程不为空
       //那么继续paused过程
        if (mPausingActivity != null) {
  // Have the window manager pause its keydispatching until the new
            // activity has started.  If we're pausing the activity just because
            // the screen is being turned offand the UI is sleeping, don't interrupt
            // key dispatch; the same activitywill pick it up again on wakeup.
            if (!uiSleeping) {
               prev.pauseKeyDispatchingLocked();
            } else if (DEBUG_PAUSE) {
                 Slog.v(TAG_PAUSE, "Keydispatch not paused for screen off");
            }
            //如果AndroidManifest.xml有设置android:resumeWhilePausing="true"该值为true
            if (dontWait) {
            // If the caller said they don'twant to wait for the pause, then complete
                     //the pause now.
                completePauseLocked(false,resuming);
                return false;
            } else {
                // Schedule a pause timeout incase the app doesn't respond.
                // We don't give it much timebecause this directly impacts the
                // responsiveness seen by theuser.
                //这个其实最终也会调用到completePauseLocked这里面,所以
                //我们接下来看看这里面操作
                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
                msg.obj = prev;
                prev.pauseTime =SystemClock.uptimeMillis();
               mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
                if (DEBUG_PAUSE)Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
                return true;
            }
        } else {
            // This activity failed to schedulethe
            // pause, so just treat it as beingpaused now.
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,"Activity not running, resuming next.");
            if (resuming == null) {
               mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }
}



我们接着上一步startPausingLocked中调用completePauseLocked过程分析,其实这个是AcrivityRecord中的PAUSING过程到PAUSED的过程。代码如下:

private void completePauseLocked(boolean resumeNext, ActivityRecordresuming) {
         //这个mPausingActivity在startPausingLocked赋值
        ActivityRecord prev =mPausingActivity;
        //表示当前正在pausing的activity不为null
        //这个流程表示处理Activity的pausing过程
        if (prev != null) {
            final booleanwasStopping = prev.state == ActivityState.STOPPING;
            //这时候Activity由PAUSIING到PAUSED
            prev.state =ActivityState.PAUSED;
            //如果这个activity状态为finish的时候直接finish该activity
            if(prev.finishing) {
             //如果pausingActivty已经finish了直接调用这个这个就不展开分析了,大致说下,如果prev处于前台,那么   //它会把该Activiyt状态切成ActivityState.STOPPGING。如果prev不处于前台,那么Activity状态
   //切成ActivityState.FINISHI,且该ActivityRecord中的finish的值改成
   //true并且通过r.app.thread.scheduleDestroyActivity调
   //用Activity的onStop、onDestory函数,这个流程完了之后通
   //过AMS的activityDestroyed函数回调ActivityStack中的
   //removeActivityFromHistoryLocked把该Activity中TaskRecord中删除,//且把状态切成      //ActivityState.Destory。
               prev =finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
            } else if(prev.app != null) {
                if(mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
                    if(DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                           "Complete pause, no longer waiting: " + prev);
                }
//这个是好像Activty configuration变化时候,并且当前activity还处//于pausing时候会置成true,这时候会重新launchActivty过程
// 具体的还没有弄明白
                if (prev.deferRelaunchUntilPaused){
                    //Complete the deferred relaunch that was waiting for pause to complete.
                    if(DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
                   relaunchActivityLocked(prev, prev.configChangeFlags, false,
                           prev.preserveWindowOnDeferredRelaunch);
                } else if(wasStopping) {
                    // We arealso stopping, the stop request must have gone soon after the pause.
       // We can't clobber it, because the stopconfirmation will not be handled.
       // We don't need toschedule another stop, we only need to let it happen.
                    prev.state= ActivityState.STOPPING;
                } else if((!prev.visible && !hasVisibleBehindActivity())
                        ||mService.isSleepingOrShuttingDownLocked()) {
       // If we were visiblethen resumeTopActivities will release resources before
       // stopping.
                    addToStopping(prev, true /*immediate */);
                }
            } else {
                prev = null;
            }

    // It is possible theactivity was freezing the screen before it was paused.
         // In that case goahead and remove the freeze this activity has on the screen
            // since it is nolonger visible.
            if (prev != null){
               prev.stopFreezingScreenLocked(true /*force*/);
            }
            //到这儿pausing过程就已经完成了,重置变量
            mPausingActivity =null;
        }
        //pausing处理完了,resumed下个Activity
        if (resumeNext) {
            finalActivityStack topStack = mStackSupervisor.getFocusedStack();
            if(!mService.isSleepingOrShuttingDownLocked()) {
               //继续调用本小章节的函数
               mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev,null);
            } else {
               mStackSupervisor.checkReadyForSleepLocked();
                ActivityRecordtop = topStack.topRunningActivityLocked();
                if (top ==null || (prev != null && top != prev)) {
                    // Ifthere are no more activities available to run, do resume anyway to start
                    //something. Also if the top activity on the stack is not the just paused
                    //activity, we need to go ahead and resume it to ensure we complete an
                    //in-flight app switch.
                   mStackSupervisor.resumeFocusedStackTopActivityLocked();
                }
            }
        }

        if (prev != null) {
           prev.resumeKeyDispatchingLocked();
            if (prev.app !=null && prev.cpuTimeAtResume > 0
   && mService.mBatteryStatsService.isOnBattery()) {
                long diff =mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
                        -prev.cpuTimeAtResume;
                if (diff >0) {
                   BatteryStatsImpl bsi =mService.mBatteryStatsService.getActiveStatistics();
                   synchronized (bsi) {
                        BatteryStatsImpl.Uid.Proc ps =
                               bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
                                       prev.info.packageName);
                        if (ps!= null) {
                            ps.addForegroundTimeLocked(diff);
                        }
                    }
                }
            }
           prev.cpuTimeAtResume = 0; // reset it
        }

        // Notify when thetask stack has changed, but only if visibilities changed (not just
        // focus). Also ifthere is an active pinned stack - we always want to notify it about
        // task stack changes,because its positioning may depend on it.
        if(mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
                ||mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) {
           mService.notifyTaskStackChangedLocked();
           mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
        }
       mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0,!PRESERVE_WINDOWS);

    }

 我们总结下这个过程,调用startPausingLocked,Activity生命周期的onPaused被调用,并且此时ActivityRecord状态经历了RESUMED->PAUSING->PAUSED的变化,经过这一步ActivityStack处于running状态的Activity已经变成PAUSED状态。

我们继续分析startPausingLocked的之后的代码,接上

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptionsoptions) {

         。。。。。。。。
 pausing |=startPausingLocked(userLeaving, false, next, dontWaitForPause);
 。。。。。。。。
         //如果当前Activity状态还示切到PAUSED,还处于PAUSING时候
         //就不再继续下面的resumed处于栈顶的activity,因为这时候resumed的
         //Activtity还未走完paused流程
        if (pausing) {
            if (DEBUG_SWITCH || DEBUG_STATES)Slog.v(TAG_STATES,
                   "resumeTopActivityLocked: Skip resume: need to startpausing");

            // At this point we want to put theupcoming activity's process
            // at the top of the LRU list,since we know we will be needing it
            // very soon and it would be awaste to let it get killed if it
            // happens to be sitting towardsthe end.

            if (next.app != null &&next.app.thread != null) {
               mService.updateLruProcessLocked(next.app, true, null);
            }
            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            return true;
        } else if (mResumedActivity == next&&next.state == ActivityState.RESUMED &&
               mStackSupervisor.allResumedActivitiesComplete()) {
// It ispossible for the activity to be resumed when we paused back stacks above if the
            // next activity doesn't have towait for pause to complete.
            // So, nothing else to-do except:
            // Make sure we have executed anypending transitions, since there
            // should be nothing left to do atthis point.
           mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES)Slog.d(TAG_STATES,
                   "resumeTopActivityLocked: Top activity resumed (dontWaitForPause)" + next);
            if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }

// If the mostrecent activity was noHistory but was only stopped rather
        // than stopped+finished because thedevice went to sleep, we need to make
        // sure to finish it as we're making anew activity topmost.
        /**
        *如果此时处于屏幕灭屏状态,并且当前Resumed的Activity设置了Intent.FLAG_ACTIVITY_NO_HISTORY
        *那么需要finish此Activity
        */
        if (mService.isSleepingLocked()&& mLastNoHistoryActivity != null &&
               !mLastNoHistoryActivity.finishing) {

            if (DEBUG_STATES)Slog.d(TAG_STATES,
                    "no-history finish of" + mLastNoHistoryActivity + " on new resume");
           requestFinishActivityLocked(mLastNoHistoryActivity.appToken,Activity.RESULT_CANCELED,
                    null,"resume-no-history", false);
            mLastNoHistoryActivity = null;
        }

        if (prev != null && prev !=next) {
  if(!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
   && next != null &&!next.nowVisible) {
               mStackSupervisor.mWaitingVisibleActivities.add(prev);
                if (DEBUG_SWITCH)Slog.v(TAG_SWITCH,
                        "Resuming top,waiting visible to hide: " + prev);
            } else {
                // The next activity is alreadyvisible, so hide the previous
                // activity's windows right nowso we can show the new one ASAP.
                // We only do this if theprevious is finishing, which should mean
                // it is on top of the onebeing resumed so hiding it quickly
                // is good.  Otherwise, we want to do the normal route ofallowing
                // the resumed activity to beshown so we can decide if the
                // previous should actually behidden depending on whether the
                // new one is found to befull-screen or not.

                if (prev.finishing) {
                   mWindowManager.setAppVisibility(prev.appToken, false);
                    if (DEBUG_SWITCH)Slog.v(TAG_SWITCH,
                            "Not waitingfor visible to hide: " + prev + ", waitingVisible="
                            +mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                            + ",nowVisible=" + next.nowVisible);

                } else {
                    if (DEBUG_SWITCH)Slog.v(TAG_SWITCH,
                            "Previous already visiblebut still waiting to hide: " + prev
                            + ",waitingVisible="
                            +mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                            + ", nowVisible="+ next.nowVisible);
                }
            }
        }

        // Launching this app's activity, makesure the app is no longer
        // considered stopped.
        try {
           AppGlobals.getPackageManager().setPackageStoppedState(
   next.packageName,false, next.userId); /* TODO: Verify if correct userid */
        } catch (RemoteException e1) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying tounstop package "
                    + next.packageName +": " + e);
        }


        // We are starting up the nextactivity, so tell the window manager
        // that the previous one will be hiddensoon.  This way it can know
        // to ignore it when computing thedesired screen orientation.
        boolean anim = true;
        if (mIsAnimationBoostEnabled == true&& mPerf == null) {
            mPerf = new BoostFramwork();
        }
        //这边是准备相关的动画,这样用户可以视觉感觉切换过程
        /读者看下就好
        if (prev != null) {
                            。。。。
        }

Bundle resumeAnimOptions = null;
        if (anim) {
            ActivityOptions opts =next.getOptionsForTargetActivityLocked();
            if (opts != null) {
                resumeAnimOptions =opts.toBundle();
            }
            next.applyOptionsLocked();
        } else {
            next.clearOptionsLocked();
        }
        ActivityStack lastStack =mStackSupervisor.getLastStack();
/*
*这之前是pausing上一个resumed的Activity,这时候就要进入栈顶的resumed过程了,
*不然栈顶的Activity永远不显示了。
*如果当前ActivityStack中,此时处于Task栈顶的Activity已经创建过了并且已经纳入相
*应的进程中,那么进入该Activity的resumed过程。
*举个例子:比如你已经通过Launcher启动了应用2中的Activity A,这时候按HOME键
*返回到Launcher桌面,这时你又点击Launcher上应用2的图标,这时候就会调用onResumed
*/
        if (next.app != null &&next.app.thread != null) {
            // If the previous activity istranslucent, force a visibility update of
            // the next activity, so that it'sadded to WM's opening app list, and
            // transition animation can be setup properly.
            // For example, pressing Homebutton with a translucent activity in focus.
            // Launcher is already visible inthis case. If we don't add it to opening
            // apps,maybeUpdateTransitToWallpaper() will fail to identify this as a
            // TRANSIT_WALLPAPER_OPENnimation, and run some funny animation.
            final booleanlastActivityTranslucent = lastStack != null
   && (!lastStack.mFullscreen
                    ||(lastStack.mLastPausedActivity != null
   && !lastStack.mLastPausedActivity.fullscreen));
            // This activity is now becomingvisible.
            if (!next.visible || next.stopped|| lastActivityTranslucent) {
               mWindowManager.setAppVisibility(next.appToken, true);
            }
            // schedule launch ticks to collectinformation about slow apps.
            next.startLaunchTickingLocked();

            ActivityRecord lastResumedActivity=
                    lastStack == null ? null:lastStack.mResumedActivity;
            ActivityState lastState =next.state;
            mService.updateCpuStats();


            if (DEBUG_STATES)Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (inexisting)");
            /**
  *这时候栈顶的Activity的activty处于RESUMED状态
  */
            next.state = ActivityState.RESUMED;
            //重新设置当前ActivityStack的resumed的activity
            mResumedActivity = next;
            next.task.touchActiveTime();
            mRecentTasks.addLocked(next.task);
           mService.updateLruProcessLocked(next.app, true, null);
            updateLRUListLocked(next);
            mService.updateOomAdjLocked();
 

            // Have the window managerre-evaluate the orientation of
            // the screen based on the newactivity order.
            boolean notUpdated = true;
            if(mStackSupervisor.isFocusedStack(this)) {
                Configuration config =mWindowManager.updateOrientationFromAppTokens(
                       mService.mConfiguration,
                       next.mayFreezeScreenLocked(next.app) ? next.appToken : null);

                if (config != null) {
                    next.frozenBeforeDestroy =true;
                }
                notUpdated =!mService.updateConfigurationLocked(config, next, false);
            }

            if (notUpdated) {
                // The configuration updatewasn't able to keep the existing
                // instance of the activity,and instead started a new one.
                // We should be all done, butlet's just make sure our activity
                // is still at the top andschedule another run if something
                // weird happened.
                ActivityRecord nextNext =topRunningActivityLocked();
                if (DEBUG_SWITCH ||DEBUG_STATES) Slog.i(TAG_STATES,
                        "Activity configchanged during resume: " + next
                        + ", new next:" + nextNext);
                if (nextNext != next) {
                    // Do over!
                    mStackSupervisor.scheduleResumeTopActivities();
                }

                if(mStackSupervisor.reportResumedActivityLocked(next)) {
                    mNoAnimActivities.clear()
                    if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
                    return true;
                }

                if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
                return false;
            }

            try {
                // Deliver all pending results.
                ArrayList<ResultInfo> a =next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing&& N > 0) {
                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                               "Delivering results to " + next + ": " + a);
                       next.app.thread.scheduleSendResult(next.appToken, a);
                    }
                }
                boolean allowSavedSurface =true;
                if (next.newIntents != null) {
                    // Restrict saved surfaceto launcher start, or there is no intent at all
                    // (eg. task being broughtto front). If the intent is something else,
                    // likely the app is goingto show some specific page or view, instead of
                    // what's left last time.

                    for (int i =next.newIntents.size() - 1; i >= 0; i--) {
                        final Intent intent =next.newIntents.get(i);
                        if (intent != null&& !ActivityRecord.isMainIntent(intent)) {
                            allowSavedSurface =false;
                            break;
                        }
                    }

                   next.app.thread.scheduleNewIntent(
                            next.newIntents,next.appToken, false /* andPause */);

                }


                // Well the app will no longerbe stopped.
                // Clear app token stoppedstate in window manager if needed.
               mWindowManager.notifyAppResumed(next.appToken, next.stopped,allowSavedSurface);
               EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
                       System.identityHashCode(next), next.task.taskId,next.shortComponentName);
                next.sleeping = false;
               mService.showUnsupportedZoomDialogIfNeededLocked(next);
                mService.showAskCompatModeDialogLocked(next);
                next.app.pendingUiClean = true;
               next.app.forceProcessStateUpTo(mService.mTopProcessState);
                next.clearOptionsLocked();
               //这边即为调用当前处于栈顶的Activity的生命
   //周期的onRestart->onResumed
                next.app.thread.scheduleResumeActivity(next.appToken,
    next.app.repProcState,
                        mService.isNextTransitionForward(),
    resumeAnimOptions);

                mStackSupervisor.checkReadyForSleepLocked();
            } catch (Exception e) {
                // Whoops, need to restart thisactivity!
                if (DEBUG_STATES)Slog.v(TAG_STATES, "Resume failed; resetting state to "
                        + lastState + ":" + next);
                next.state = lastState;
                if (lastStack != null) {
                    lastStack.mResumedActivity= lastResumedActivity;
                }
                Slog.i(TAG, "Restarting becauseprocess died: " + next);
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched =true;
                } else  if (SHOW_APP_STARTING_PREVIEW &&lastStack != null &&
                        mStackSupervisor.isFrontStack(lastStack)) {
                   next.showStartingWindow(null, true);
                }
               mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
            // From this point on, if somethinggoes wrong there is no way
            // to recover the activity.
            try {
                //这时候activity的状态为visible
                completeResumeLocked(next);
            } catch (Exception e) {
                // If any exception getsthrown, toss away this
                // activity and try the nextone.
                Slog.w(TAG, "Exceptionthrown during resume of " + next, e);
               requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED,null,
                       "resume-exception", true);
                if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
        } else {//这个流程创建进程时候已经分析过了

            // Whoops, need to restart thisactivity!
            if (!next.hasBeenLaunched) {
   next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW){
   next.showStartingWindow(null, true);
                }
            }
           mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
        return true;
}

  经过这一小章节的解析,AMS会先startPausingLocked函数中paused之前的resumed的Activity,这时候Activity生命周期的onPaused被调用,并且此时ActivityRecord状态经历了RESUMED->PAUSING->PAUSED的变化,接下来是resumed当前activityStack处于栈顶的Activity,它把当前ActivityStack的resumed的activity修改成当前栈顶的activity,栈顶Activity的状态对应修改成RESUMED,并且调用Activity的生命周期onStart->onResume,最后设置其visible为true。

         到这儿其实关于Activity生命中的onStop和onDestory还没有介绍,因为之前只是在Activity切换,并没有涉及到Activity结束的情况。那么onStop和onDestory何时会调用呢?

         举一个情况来分析,我们知道应用中Activity调用finish 函数是会结束当前Activity的,我们以这个作为切入来点分析。调用finish最终会调用到AMS中的finishActivity当中,我们简化当前finsi的activity不是root Activity(即不是AndroidManifest有定义Main的activity)。

finishActivity会它所属的activityStack中的requestFinishActivityLocked函数,代码如下:

final boolean requestFinishActivityLocked(IBinder token, int resultCode,
           Intent resultData, String reason, boolean oomAdj) {
       ActivityRecord r = isInStackLocked(token);

       if (r == null) {
           return false;
       }
       finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
       return true;
    }
进入finishActivityLocked代码如下:

/**
     * @return Returns true if this activityhas been removed from the history
     * list, or false if it is still in thelist and will be removed later.
     */
    final booleanfinishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
            String reason, boolean oomAdj) {
        if (r.finishing) {
            Slog.w(TAG, "Duplicate finishrequest for " + r);
            return false;

        }

                   //在这儿会把activityRecord中的finishing设置为true

                   //表示该activity正在处于finishing过程

        r.makeFinishingLocked();
        final TaskRecord task = r.task;
        final ArrayList<ActivityRecord>activities = task.mActivities;
        final int index =activities.indexOf(r);

        if (index < (activities.size() - 1)){
            task.setFrontOfTask();
            if ((r.intent.getFlags() &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
                // If the caller asked thatthis activity (and all above it)
                // be cleared when the task isreset, don't lose that information,
                // but propagate it up to thenext activity.
                ActivityRecord next =activities.get(index+1);
               next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
            }
        }
        r.pauseKeyDispatchingLocked();
        //需要重新设置下当前focused的activity
        adjustFocusedActivityLocked(r,"finishActivity");
        finishActivityResultsLocked(r,resultCode, resultData);
        final boolean endTask = index <= 0;
        final int transit = endTask ?AppTransition.TRANSIT_TASK_CLOSE : AppTransition.TRANSIT_ACTIVITY_CLOSE;
        /**
         当前Resumed的activity(即当前running状态)自身调用finish
        */
        if (mResumedActivity == r) {

            if (DEBUG_VISIBILITY ||DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                    "Prepare closetransition: finishing " + r);
           mWindowManager.prepareAppTransition(transit, false)
            // Tell window manage to preparefor this one to be removed.
           mWindowManager.setAppVisibility(r.appToken, false);
            if (mPausingActivity == null) {
                if (DEBUG_PAUSE)Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
                if (DEBUG_USER_LEAVING)Slog.v(TAG_USER_LEAVING,
                        "finish() =>pause with userLeaving=false");
                                     //这个之前分析过了,大家注意下参数不同走的流程不同就好
                                     //最终这个也会进入finishCurrentActivityLocked
                startPausingLocked(false,false, null, false);
            }

            if (endTask) {
               mStackSupervisor.removeLockedTaskLocked(task);
            }
        } else if (r.state !=ActivityState.PAUSING) {
                            //看注释
            // If the activity is PAUSING, wewill complete the finish once
            // it is done pausing; else we canjust directly finish it here.
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,"Finish not pausing: " + r);
            if (r.visible) {
               mWindowManager.prepareAppTransition(transit, false);
               mWindowManager.setAppVisibility(r.appToken, false);
               mWindowManager.executeAppTransition();
                if(!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
                   mStackSupervisor.mWaitingVisibleActivities.add(r);
                }
            }
           //这儿正式结束activity
            returnfinishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
                    FINISH_AFTER_VISIBLE :FINISH_AFTER_PAUSE, oomAdj) == null;
        } else {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,"Finish waiting for pause of: " + r);
        }
        return false;
    }

         我们分析下这个finishCurrentActivityLocked函数,代码如下:

final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
        // First things first: if this activityis currently visible,
        // and the resumed activity is not yetvisible, then hold off on
        // finishing until the resumed onebecomes visible.
       //经过上一步调用makeFinishingLocked之后,当前处于栈顶的running已经变化了
       //比如此时栈有A,B,C这三个,原来如果为topRunning为C,
 //这时经过makeFinishingLocked之后,topRunning变成了B
        final ActivityRecord next =mStackSupervisor.topRunningActivityLocked();
      //这个是比如当前finish的Acity还处于可视状态,那么他的状态先切成了STOPPING
        if (mode == FINISH_AFTER_VISIBLE&& (r.visible || r.nowVisible)
                && next != null&& !next.nowVisible) {
            if(!mStackSupervisor.mStoppingActivities.contains(r)) {
                addToStopping(r, false /*immediate */);
            }
            if (DEBUG_STATES) Slog.v(TAG_STATES,
                    "Moving to STOPPING:"+ r + " (finish requested)");
            r.state = ActivityState.STOPPING;
            if (oomAdj) {
                mService.updateOomAdjLocked();
            }
            return r;
        }

       // make sure the record is cleaned out of other places.
       mStackSupervisor.mStoppingActivities.remove(r);
       mStackSupervisor.mGoingToSleepActivities.remove(r);
       mStackSupervisor.mWaitingVisibleActivities.remove(r);

        if (mResumedActivity == r) {
            mResumedActivity = null;
        }

        final ActivityState prevState =r.state;
        if (DEBUG_STATES) Slog.v(TAG_STATES,"Moving to FINISHING: " + r);
                   //这时候Activity状态转换成FINISHING
        r.state = ActivityState.FINISHING;
        final booleanfinishingActivityInNonFocusedStack
                = r.task.stack !=mStackSupervisor.getFocusedStack()
                && prevState ==ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;
 
        if (mode == FINISH_IMMEDIATELY
                || (prevState ==ActivityState.PAUSED
                    && (mode ==FINISH_AFTER_PAUSE || mStackId == ActivityManager.StackId.PINNED_STACK_ID))
                ||finishingActivityInNonFocusedStack
               || prevState == ActivityState.STOPPED
                || prevState ==ActivityState.INITIALIZING) {
            r.makeFinishingLocked()

 
 /*这边开始调用Activity生命周期的onStop->onDestory,如果当前还未paused*的还会onPaused这个生命周期,这函数  *里面会把Activity从
           *对应的进程中删除,nowVisible变成false,,
            *把Activity从对应的Task中移除并且状态修改成DESTROYED
            *从WindowMangerService删除对应的Activity
          */
            boolean activityRemoved =destroyActivityLocked(r, true, "finish-imm");

 

            if(finishingActivityInNonFocusedStack) {
                // Finishing activity that was in pausedstate and it was in not currently focused
                // stack, need to makesomething visible in its place.
               mStackSupervisor.ensureActivitiesVisibleLocked(null, 0,!ActivityStackSupervisor.PRESERVE_WINDOWS);
            }

            if (activityRemoved){             mStackSupervisor.resumeFocusedStackTopActivityLocked();

            }

            if (DEBUG_CONTAINERS)Slog.d(TAG_CONTAINERS,
                   "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
                    " destroy returnedremoved=" + activityRemoved);
            return activityRemoved ? null : r;
        }

 

        // Need to go through the full pause cycleto get this
        // activity into the stopped state andthen finish it.
        if (DEBUG_ALL) Slog.v(TAG,"Enqueueing pending finish: " + r);
       mStackSupervisor.mFinishingActivities.add(r);
        r.resumeKeyDispatchingLocked();
        mStackSupervisor.resumeFocusedStackTopActivityLocked();
        return r;
    }

  到这儿我们就能知道Activity生命周期中的onStop->onDestory了,Activity状态转换

FINISHING->DESTORYING->DESTORYED,已经从相关的进程和Task移除Activity。

好了,到了这步一个启动的Activity整个生命流程算是介绍完了,涉及东西异常多、和繁锁,读者需要自己拿着代码,可以对着流程自己梳理,其中还有很多在这篇文章里没有涉及,忽略很多,毕竟AMS涉及东西太多。晕!!!!

开机广播BOOT_COMPLETED发送流程

何时发送BOOT_COMPLETED广播,这章节我简单说下,看下流程怎么走。

我们接上一章节Activity初始化中的minimalResumeActivityLocked进行分析:

void inimalResumeActivityLocked(ActivityRecord r) {
        r.state = ActivityState.RESUMED;
        mResumedActivity = r;
        r.task.touchActiveTime();
        mRecentTasks.addLocked(r.task);
///
        completeResumeLocked(r);
       mStackSupervisor.checkReadyForSleepLocked();
        setLaunchTime(r);
        if (DEBUG_SAVED_STATE)Slog.i(TAG_SAVED_STATE,
                "Launch completed;removing icicle of " + r.icicle);
    

分析completeResumeLocked:

 

 private voidcompleteResumeLocked(ActivityRecord next) {
        next.visible = true;
        next.idle = false;
        next.results = null;
        next.newIntents = null;
        next.stopped = false;

        if (next.isHomeActivity()) {
            ProcessRecord app =next.task.mActivities.get(0).app;
            if (app != null && app !=mService.mHomeProcess) {
                mService.mHomeProcess = app;
            }
        }
        if (next.nowVisible) {
            // We won't get a call toreportActivityVisibleLocked() so dismiss lockscreen now.
            mStackSupervisor.reportActivityVisibleLocked(next);
           mStackSupervisor.notifyActivityDrawnForKeyguard();
        }
        // schedule an idle timeout in case theapp doesn't do it for us.
       mStackSupervisor.scheduleIdleTimeoutLocked(next);
                            。。。。。。。。

    }

 进入scheduleIdleTimeoutLocked,这个函数实际上是通过Handler最终调用activityIdleInternalLocked

final ActivityRecord activityIdleInternalLocked(final IBinder token, booleanfromTimeout,
            Configuration config) {
。。。。。。
        ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (r != null) {
            if (isFocusedStack(r.task.stack) ||fromTimeout) {
                booting =checkFinishBootingLocked();
            }
        }
 
。。。。。。。
    }

进入checkFinishBootingLocked:代码如下

private boolean checkFinishBootingLocked() {
        final boolean booting =mService.mBooting;
        boolean enableScreen = false;
        mService.mBooting = false;
        if (!mService.mBooted) {
            mService.mBooted = true;
            enableScreen = true;
        }

        if (booting || enableScreen) {
            mService.postFinishBooting(booting,enableScreen);
        }

        return booting;
    }

继续进入AMS中的postFinishBooting,在该函数通过Handler,最终进入finishBooting

final void finishBooting() {
        synchronized (this) {
。。。。。
         /**开始发送广播*/
               mUserController.sendBootCompletedLocked(
                        newIIntentReceiver.Stub() {
                            @Override
                            public voidperformReceive(Intent intent, int resultCode,
                                    Stringdata, Bundle extras, boolean ordered,
                                    booleansticky, int sendingUser) {
                                synchronized(ActivityManagerService.this) {
                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
                                           true, false);
                                }
                            }
                        });
                scheduleStartProfilesLocked();
            }
        }
    }
进入sendBootCompletedLocked进行分析
void sendBootCompletedLocked(IIntentReceiver resultTo) {

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

            UserState uss =mStartedUsers.valueAt(i);

            finishUserBoot(uss, resultTo);

        }

    }

接着进入finishUserBoot

private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
。。。。。。。。
            // We need to delay unlockingmanaged profiles until the parent user
            // is also unlocked.
            if(getUserManager().isManagedProfile(userId)) {
                final UserInfo parent =getUserManager().getProfileParent(userId);
                if (parent != null
    &&isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
                    Slog.d(TAG, "User" + userId + " (parent " + parent.id
                            + "):attempting unlock because parent is unlocked");
                    maybeUnlockUser(userId);
                } else {
                    String parentId = (parent == null) ?"<null>" : String.valueOf(parent.id);
                    Slog.d(TAG, "User" + userId + " (parent " + parentId
                            + "): delayingunlock because parent is locked");
                }
            } else {
                maybeUnlockUser(userId);
            }
        }
    }

接着进入maybeUnlockUser看看

boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
            IProgressListener listener) {
        UserState uss;
。。。。。。
 finishUserUnlocking(uss);
。。。。。。。
        return true;
    }

继续进入finishUserUnlocking

         private void finishUserUnlocking(finalUserState uss) {
        final int userId =uss.mHandle.getIdentifier();
。。。。。。
        if (proceedWithUnlock) {
            uss.mUnlockProgress.start();
 
            // Prepare app storage before we goany further
            uss.mUnlockProgress.setProgress(5,
            mService.mContext.getString(R.string.android_start_title));
            mUserManager.onBeforeUnlockUser(userId);
           uss.mUnlockProgress.setProgress(20);



            // Dispatch unlocked to systemservices; when fully dispatched
            // that calls through to the next"unlocked" phase
           mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
                    .sendToTarget();

        }

    }


通过发送一个消息SYSTEM_USER_UNLOCK_MSG到AMS中,AMS中再回调

mUserController.finishUserUnlocked((UserState)msg.obj);

void finishUserUnlocked(final UserState uss) {
        final int userId =uss.mHandle.getIdentifier();
。。。。。。。
                } else {
                   finishUserUnlockedCompleted(uss);
                }
            }
        }
    }

继续分析finishUserUnlockedCompleted

private void finishUserUnlockedCompleted(UserStateuss) {
        final int userId =uss.mHandle.getIdentifier();

        synchronized (mService) {
            // Bail if we ended up with a staleuser
            if(mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
            final UserInfo userInfo =getUserInfo(userId);
            if (userInfo == null) {
                return;
            }

            // Only keep marching forward ifuser is actually unlocked
            if (!StorageManager.isUserKeyUnlocked(userId))return;
 
            // Remember that we logged in
           mUserManager.onUserLoggedIn(userId);

            if (!userInfo.isInitialized()) {
                if (userId !=UserHandle.USER_SYSTEM) {
                    Slog.d(TAG,"Initializing user #" + userId);
                    Intent intent = newIntent(Intent.ACTION_USER_INITIALIZE);
                   intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                    mService.broadcastIntentLocked(null,null, intent, null,
                            newIIntentReceiver.Stub() {
                                @Override
                                public voidperformReceive(Intent intent, int resultCode,
                                        String data, Bundle extras, booleanordered,
                                        booleansticky, int sendingUser) {
                                    // Note:performReceive is called with mService lock held
                                    getUserManager().makeInitialized(userInfo.id);
                                }
                            }, 0, null, null,null, AppOpsManager.OP_NONE,
                            null, true, false,MY_PID, SYSTEM_UID, userId);
                }
            }

            Slog.d(TAG, "SendingBOOT_COMPLETE user #" + userId);
            int uptimeSeconds =(int)(SystemClock.elapsedRealtime() / 1000);
           MetricsLogger.histogram(mService.mContext,"framework_boot_completed", uptimeSeconds);
//这时候就开始发送BOOT_COMPLETED消息了
            final Intent bootIntent = newIntent(Intent.ACTION_BOOT_COMPLETED, null);
           bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
           bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
                    |Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
           mService.broadcastIntentLocked(null, null, bootIntent, null, null, 0,null, null,
                    new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
                    AppOpsManager.OP_NONE, null, true,false, MY_PID, SYSTEM_UID, userId);
        }
    }

发送BOOT_COMPLETED消息流程简单的描述了下,即在Launcher启动完毕之后,AMS开始发送该广播。

         本文介绍了下AMS中关于如何管理Activity,但是没有涉及到WindowManagerService相关界面的显示,这个只是梳理下Activity在AMS中如何表现。文章有错误的地方还请读者指出来,有疑问也可以提出来。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值