AMS剖析(2):Activity在AMS中的啓動

前言:前面已經分析了AMS的啓動,接下來就開始分析AMS的數據結構以及AMS與ActivityThread的交互;

這一篇我們跟着一個Activity的啓動流程,來分析AMS的數據結構,基於android9.0的framework源碼;

Activity的啓動過程分爲兩種,一種是根Acitivity的啓動過程,另一種是普通Activity的啓動過程;

①根Activity指的是應用程序啓動的第一個Activity,所以根Activity的啓動過程,也稱爲應用程序的啓動過程;

②普通Activity指的是除應用程序啓動的第一個Activity之外的其他Activity;

我們分析的是根Activity的啓動流程;

接下來慢慢分析:

1.Launcher請求AMS

我們知道,Launcher啓動後會將已安裝的應用程序的快捷圖標顯示到桌面,這些應用程序的快捷圖標就是啓動根Activity的入口;我們就以點擊Settings應用即"設置"的快捷圖標爲例,來分析根Activity的啓動流程;

當我們在Launcher中點擊Settings圖標時會調用如下代碼:

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent,optBundle);

點評:將Flag設置爲Intent.FLAG_ACTIVITY_NEW_TASK,這樣根Activity會在新的任務棧中啓動;

Settings的intent中,除了上述的flag信息外,還有如下信息:

Action:android.intent.action.MAIN;
Categories:android.intent.category.LAUNCHER;
Component:要啓動的Activity組件,值爲com.android.settings/.Settings;
Flag:啓動標記,FLAG_ACTIVITY_NEW_TASK;

接下來看startActivity(intent,optBundle)方法在Activity中實現,代碼如下:

Activity.java
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        //第二個參數爲-1,表示Launcher不需要知道Activity的啓動結果;
        //options爲攜帶的信息,它用於指定啓動Activity的自定義動畫和縮放動畫
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

點評:我們的代碼走這一句,startActivityForResult(intent, -1, options),繼續看:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        //mParent表示當前Activity的父類,Launcher沒有父親

        options = transferSpringboardActivityOptions(options);

        //接下來調用Instrumentation的execStartActivity方法
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        
        //對於requestCode<0的情況,ar爲null;
        //這裏的requestCode爲-1,表示不需要返回結果
        if (ar != null) {//獲取啓動Activity的返回結果
            //根據Settings的返回結果,調用Launcher的onActivityResult方法;
            //ar==null,因爲mInstrumentation.execStartActivity()的返回結果必定是null;
            //這個屬於AMS與AcitivtyThread交互的範疇,先不討論
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }
        cancelInputsAndStartExitTransition(options);
    } else {//子Activity,最終調用mInstrumentation.execStartActivity
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

點評:①Instrumentation是用來監控應用程序和系統的交互,啓動應用程序的Activity需要與ActivityManagerService交互,因此需要通過Instrumentation代理並監控啓動請求的處理;這裏的mInstrumentation屬於Launcher,我們後面會詳細分析根Acitivty的Instrumentation;

②mToken是IBinder類型的對象,其本質是一個BinderProxy,通過該Binder代理可以訪問當前Activity(本例爲Launcher)在ActivityManagerService中對應的ActivityRecord;ActivityRecord記錄了當前Activity的信息, AMS需要獲取這些信息;

③mMainThread是ActivityThread類型的對象,表示應用程序主線程,本例中代表的是Launcher的主線程。ActivityThread有一個 ApplicationThread類型的成員變量,定義了調度當前Activity的方法,可以通過mMainThread.getApplicationThread方法返回該成員變量。

這三個變量在後面會詳解,這裏先簡單的介紹一下,知道它們的意義即可;

繼續看代碼:

Instrumentation.java
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ............
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        //調用ActivityManager的getService()方法獲取AMS得代理對象,接着調用AMS的startActivity方法
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        //檢查是否啓動成功,如果Activity啓動失敗,result會告訴我們失敗的原因
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }

    return null;
}

點評:我們來看ActivityManager.getService()是如何得到AMS的;

ActivityManager.java
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                //得到IBinder類型的AMS的引用
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                //將"IBinder類型的AMS的引用"轉換成"IActivityManager類型的對象",這段代碼採用的是AIDL,採用跨進程通信
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

點評:從上面得知, mInstrumentation.execStartActivity()最終調用的是AMS.startActivity();

我們先來做個小總結:

①點擊Launcher中Settings圖標,會調用Launcher.startActivity(),進而調用Launcher的父類Activity的startActivity方法;

②Activity.startActivity()調用Activity.startActivityForResult()方法,傳入該方法的requestCode參數爲-1,表示Activity啓動成功後,不需要執行Launcher.onActivityResult()方法處理返回結果;

③啓動Activity需要與系統AMS交互,必須納入Instrumentation的監控,因此需要將啓動請求轉交Instrumentation,即調用Instrumentation. execStartActivity方法;

④Instrumentation.execStartActivity()首先通過ActivityMonitor檢查啓動請求,然後通過ActivityManager.getService()方法獲取AMS的代理對象,接着調用AMS的startActivity方法。通過IPC,Binder驅動將處理邏輯從Launcher所在進程切換到AMS所在進程。

接下來我們就進入到AMS了;

 

2.AMS到ApplicaitonThread的調用過程

ActivityManagerService.java
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    //UserHandle.getCallingUserId()表示調用者的UserId,AMS會根據這個UserId來確定調用者的權限
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

點評: 在分析AMS的startActivity方法之前,我們先來看一下該方法傳遞進來的參數信息;

caller:Launcher的ApplicationThread,即請求者的ApplicationThread;

callingPackage:Launcher的包名,即請求者的包名;

intent:意圖,這個容易理解;

resolvedType:標識Intent數據的MIME類型,可以通過Intent.setDataAndType()設置,這裏可以理解爲null;

resultTo:令牌,標識接受返回結果的一方,是一個ActivityRecord的IBinder引用;

resultWho:暫時把它理解成是一個id,與調用者的包名有關;

requestCode:請求碼,這裏是-1;

startFlags:這裏爲0;

profilerInfo:這裏爲null;

bOptions:傳遞進來的動畫參數;

我們發現startActivityAsUser方法比startActivity方法多了一個參數UserHandle.getCallingUserId(),也就是說,startActivityAsUser方法這個方法會獲得調用者的UserId,AMS會根據這個UserId來確定調用者的權限;

這些參數都瞭解了,接下來繼續看startActivityAsUser()方法:

public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    //多了一個參數true,表示驗證調用者
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
            true /*validateIncomingUser*/);
}

public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
        boolean validateIncomingUser) {
    //檢查調用者即Launcher進程是否有權限啓動Activity,如果沒權限,拋出異常
    enforceNotIsolatedCaller("startActivity");

    //檢查調用者Laucher這個Activity是否有權限啓動Settings,如果沒有權限也會拋出異常
    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

    //獲取到ActivityStarter,並調用ActivityStarter的execute()方法
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();
}

點評:上述代碼主要是檢查調用者的進程以及調用者的權限,最後通過 mActivityStartController.obtainStarter()得到ActivityStarter,ActivityStarter是一個代理類,代理AMS與App進行通信,類似於Activity中的Instrumentation,AMS在每一次startActivity方法的調用過程中,都會創建一個ActivityStarter來進行代理;

得到ActivityStarter後調用ActivityStarter的execute()方法,初始化ActivityStarter的過程是一個典型的Builder模式,繼續來看ActivityStarter.execute():

 

ActivityStarter.java
int execute() {
    try {
        if (mRequest.mayWait) {
            //只要調用了setMayWait()方法,mRequest.mayWait就爲true,所以走下面這段代碼
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                    mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                    mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                    mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                    mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        } else {
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                    mRequest.outActivity, mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        }
    } finally {
        onExecutionComplete();
    }
}

點評:startActivityMayWait()的返回值就是啓動Activity的結果,我們看到startActivityMayWait()方法中有很多參數,mRequest只是一個對象,它用來將AMS中傳遞過來的參數進行封裝,優化了代碼;

我們再來看下它多了哪幾個參數吧:

mRequest.waitResult:由於不需要等待Activity的返回結果,所以這裏爲null;

mRequest.globalConfig:全局配置,這裏也是null;

mRequest.activityOptions:對bOptions的調整以及封裝;

mRequest.ignoreTargetSecurity:是否忽視目標的安全性,這裏是false,表示不能忽視;

mRequest.userId:調用者的id;

mRequest.inTask:TaskRecord,啓動的Activity,也就是根Activity所在的棧,目前是null;

mRequest.reason:啓動Activity的理由,這裏的理由就是"startActivityAsUser";

mRequest.allowPendingRemoteAnimationRegistryLookup:允許從Activity開始檢查,這裏爲false,即不允許;

好,下面繼續看startActivityMayWait()方法:

private int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, WaitResult outResult,
        Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
        int userId, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {
    // Refuse possible leaked file descriptors
    if (intent != null && intent.hasFileDescriptors()) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }
    mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();

    //傳入的intent包含ComponentName的信息,這裏的componentSpecified爲true
    boolean componentSpecified = intent.getComponent() != null;

    final int realCallingPid = Binder.getCallingPid();
    final int realCallingUid = Binder.getCallingUid();

    //設置callingPid,callingUid,用於區分調用者是否來自於應用程序
    int callingPid;
    if (callingUid >= 0) {
        callingPid = -1;
    } else if (caller == null) {
        //啓動Launcher或者使用am start啓動一個應用程序時,caller便爲null,此時需要記錄調用方的PID和UID;
        callingPid = realCallingPid;
        callingUid = realCallingUid;
    } else {
        callingPid = callingUid = -1;
    }

    //後續操作會修改客戶端傳進來的Inent,這裏重新封裝,防止修改原始Intent
    final Intent ephemeralIntent = new Intent(intent);
    intent = new Intent(intent);

    //如果是啓動一個臨時應用,不應該以原始意圖啓動,而應調整意圖,使其看起來像正常的即時應用程序啓動
    if (componentSpecified
            && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
            && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
            && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
            && mService.getPackageManagerInternalLocked()
                    .isInstantAppInstallerComponent(intent.getComponent())) {
        // intercept intents targeted directly to the ephemeral installer the
        // ephemeral installer should never be started with a raw Intent; instead
        // adjust the intent so it looks like a "normal" instant app launch
        intent.setComponent(null /*component*/);
        componentSpecified = false;
    }

    //查詢與intent匹配的Activity,rInfo中包含了查找信息;
    //mSupervisor.resolveIntent()會調用PKMS方法獲取該Activity的信息
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
            0 /* matchFlags */,
                    computeResolveFilterUid(
                            callingUid, realCallingUid, mRequest.filterCallingUid));
    if (rInfo == null) {
        UserInfo userInfo = mSupervisor.getUserInfo(userId);
        if (userInfo != null && userInfo.isManagedProfile()) {
            UserManager userManager = UserManager.get(mService.mContext);
            boolean profileLockedAndParentUnlockingOrUnlocked = false;
            long token = Binder.clearCallingIdentity();
            try {
                UserInfo parent = userManager.getProfileParent(userId);
                profileLockedAndParentUnlockingOrUnlocked = (parent != null)
                        && userManager.isUserUnlockingOrUnlocked(parent.id)
                        && !userManager.isUserUnlockingOrUnlocked(userId);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
            if (profileLockedAndParentUnlockingOrUnlocked) {
                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                        PackageManager.MATCH_DIRECT_BOOT_AWARE
                                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                        computeResolveFilterUid(
                                callingUid, realCallingUid, mRequest.filterCallingUid));
            }
        }
    }

    //從rInfo中得到aInfo,aInfo表示運行時的Activity信息
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

    synchronized (mService) {
        final ActivityStack stack = mSupervisor.mFocusedStack;
        //是否需要修改Configuration信息,此處爲false
        stack.mConfigWillChange = globalConfig != null
                && mService.getGlobalConfiguration().diff(globalConfig) != 0;
        if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                "Starting activity when config will change = " + stack.mConfigWillChange);

        final long origId = Binder.clearCallingIdentity();

        //下面是判斷該Acitivity是否是一個重量級的進程;
        /*FLAG_CANT_SAVE_STATE由AndroidManifest.xml的Application標籤指定,該標籤並未對SDK開放;
        系統中只有development/samples/HeavyWeight這一個示例應用使用到,因此,這個判斷可以忽略掉*/
        if (aInfo != null &&
                (aInfo.applicationInfo.privateFlags
                        & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
                mService.mHasHeavyWeightFeature) {
            ............        
        }

        final ActivityRecord[] outRecord = new ActivityRecord[1];
        //將請求發送給startActivity()去執行,返回啓動結果
        int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                allowPendingRemoteAnimationRegistryLookup);

        Binder.restoreCallingIdentity(origId);

        //更新Configuration
        if (stack.mConfigWillChange) {
   mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                    "updateConfiguration()");
            stack.mConfigWillChange = false;
            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                    "Updating to new configuration after starting activity.");
            mService.updateConfigurationLocked(globalConfig, null, false);
        }

        //此例傳入的outResult爲null,不執行這步;
        // 只有調用ActivityManagerService的startActivityAndWait方法時,傳入的outResult參數不爲null,
        //但startActivityAndWait方法只在通過am start-W啓動Activity的時候用到。-W的意思是wait*/
        if (outResult != null) {
        	............
        }

        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
        return res;
    }
}

點評:startActivityMayWait方法的主要工作如下:

①調用mSupervisor.resolveIntent方法經由PackageManagerService查詢系統中是否存在處理指定Intent的Activity,即找到Settings;

②根據caller判斷啓動Activity的客戶端是應用程序還是其他進程(如adb shell);

③處理FLAG_CANT_SAVE_STATE標記,該標記目前只在示例程序中使用;

④繼續調用ActivityStarter.startActivity執行後續操作;

⑤處理Configuration需要改變的情況,對於啓動Settings應用,則不需要改變;

⑥處理wait狀態,正常啓動應用程序不需要執行這個步驟,此例中startActivityMayWait其實是startActivity" Not" Wait;

startActivityMayWait啓動Activity的後續工作放在startActivity()方法中完成,繼續看:

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {

    //啓動理由不能爲null
    if (TextUtils.isEmpty(reason)) {
        throw new IllegalArgumentException("Need to specify a reason.");
    }
    mLastStartReason = reason;
    mLastStartActivityTimeMs = System.currentTimeMillis();
    mLastStartActivityRecord[0] = null;

    //又調用startActivity()方法
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask, allowPendingRemoteAnimationRegistryLookup);

    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }

    return getExternalResult(mLastStartActivityResult);
}

繼續調用startActivity()方法:

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        SafeActivityOptions options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle
            = options != null ? options.popAppVerificationBundle() : null;

    ProcessRecord callerApp = null;
    //caller是Launcher所在的應用程序進程的ApplicationThread對象
    if (caller != null) {
        //得到代表Launcher進程的callerApp對象,它是ProcessRecord類型,ProcessRecord用於描述一種應用程序進程
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            //獲取Launcher進程的pid和uid
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }

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

    ActivityRecord sourceRecord = null;
    ActivityRecord resultRecord = null;
    //傳入的resultTo代表Launcher
    if (resultTo != null) {
        ////取出Launcher的ActivityRecord
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {
            /*傳入的requestCode爲-1,即不需要返回結果。對於需要返回結果的情況,發起startActivity的一方便是接收返回結果的一方(只要其狀態不是finishing)。
            只有調用startActivityForResult時,傳入的參數requestCode>=0纔會接收返回結果*/
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }

    final int launchFlags = intent.getFlags();

    //獲取Intent存儲的啓動標記flag,處理FLAG_ACTIVITY_FORWARD_RESULT標記,我們沒有設置此標記
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        if (requestCode >= 0) {
            SafeActivityOptions.abort(options);
            return ActivityManager.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) {
            callingPackage = sourceRecord.launchedFromPackage;
        }
    }
    
    if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
        err = ActivityManager.START_INTENT_NOT_RESOLVED;
    }

    if (err == ActivityManager.START_SUCCESS && aInfo == null) {
        err = ActivityManager.START_CLASS_NOT_FOUND;
    }

    //Activity作爲語音會話的一部分啓動,這個暫時沒討論
    if (err == ActivityManager.START_SUCCESS && sourceRecord != null
            && sourceRecord.getTask().voiceSession != null) {
       ............
    }

    //關於語音的,先pass
    if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
        ............
    }

    final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();

    if (err != START_SUCCESS) {
        /*指定了接收啓動結果的Activity,通過sendActivityResultLocked將錯誤結果返回,該錯誤結果爲RESULT_CANCELED*/
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(
                    -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
        }
        SafeActivityOptions.abort(options);
        return err;
    }

    //檢查是否有啓動Activity的權限*/
    boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
            requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
            inTask != null, callerApp, resultRecord, resultStack);
    abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
            callingPid, resolvedType, aInfo.applicationInfo);

    // Merge the two options bundles, while realCallerOptions takes precedence.
    ActivityOptions checkedOptions = options != null
            ? options.getOptions(intent, aInfo, callerApp, mSupervisor)
            : null;
    if (allowPendingRemoteAnimationRegistryLookup) {
        checkedOptions = mService.getActivityStartController()
                .getPendingRemoteAnimationRegistry()
                .overrideOptionsIfNeeded(callingPackage, checkedOptions);
    }

    ///Add for application lock start
    //爲應用程序鎖定啓動添加
    if (mService.mAppsLockOps != null) {

        int result = mService.mAppsLockOps.isPackageNeedLocked(
                aInfo.applicationInfo.packageName,
                aInfo.name,
                mService.isSleepingLocked(),
                userId);

        if (result == GomeApplicationsLockOps.APPLICATION_LOCK_SHOULD_LOCK) {
            Intent watchIntent = (Intent) intent.clone();
            Bundle bOption = null;

            if(checkedOptions != null) {
                bOption = checkedOptions.toBundle();
            }
            if (mService.showAccessOnTopRunningActivity(watchIntent,
                    aInfo.applicationInfo.packageName,
                    userId, requestCode, resultWho, bOption, caller, mLastStartReason)) {
                ActivityOptions.abort(checkedOptions);
                return ActivityManager.START_SUCCESS;
            }
        }
    }
    ///Add for application lock end

    //IActivityController是AMS的監聽器,我們這裏沒有設置
    if (mService.mController != null) {
        try {
            // The Intent we give to the watcher has the extra data
            // stripped off, since it can contain private information.
            Intent watchIntent = intent.cloneFilter();
            //決定是否啓動當前請求啓動的Activity
            abort |= !mService.mController.activityStarting(watchIntent,
                    aInfo.applicationInfo.packageName);
        } catch (RemoteException e) {
            mService.mController = null;
        }
    }

    mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
    if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
            callingUid, checkedOptions)) {
        intent = mInterceptor.mIntent;
        rInfo = mInterceptor.mRInfo;
        aInfo = mInterceptor.mAInfo;
        resolvedType = mInterceptor.mResolvedType;
        inTask = mInterceptor.mInTask;
        callingPid = mInterceptor.mCallingPid;
        callingUid = mInterceptor.mCallingUid;
        checkedOptions = mInterceptor.mActivityOptions;
    }

    if (abort) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                    RESULT_CANCELED, null);
        }
        ActivityOptions.abort(checkedOptions);
        return START_ABORTED;
    }

    if (mService.mPermissionReviewRequired && aInfo != null) {
        if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                aInfo.packageName, userId)) {
            IIntentSender target = mService.getIntentSenderLocked(
                    ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                    callingUid, userId, null, null, 0, new Intent[]{intent},
                    new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
                            | PendingIntent.FLAG_ONE_SHOT, null);

            final int flags = intent.getFlags();
            Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
            newIntent.setFlags(flags
                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
            newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
            if (resultRecord != null) {
                newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
            }
            intent = newIntent;

            resolvedType = null;
            callingUid = realCallingUid;
            callingPid = realCallingPid;

            rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
                    computeResolveFilterUid(
                            callingUid, realCallingUid, mRequest.filterCallingUid));
            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
                    null /*profilerInfo*/);
        }
    }

    if (rInfo != null && rInfo.auxiliaryInfo != null) {
        intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
                callingPackage, verificationBundle, resolvedType, userId);
        resolvedType = null;
        callingUid = realCallingUid;
        callingPid = realCallingPid;

        aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
    }

    //創建即將要啓動的Activity即Settings的描述類ActivityRecord;
    //同ProcessRecord一樣,ActivityRecord用來描述一個Activity,用來記錄一個Activity的所有信息
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
            mSupervisor, checkedOptions, sourceRecord);
    if (outActivity != null) {
        //將ActivityRecord賦值給outActivity
        outActivity[0] = r;
    }

    if (r.appTimeTracker == null && sourceRecord != null) {
        r.appTimeTracker = sourceRecord.appTimeTracker;
    }

    //獲取當前正在顯示的ActivityStack,這裏指的是Launcher所在的ActivityStack
    final ActivityStack stack = mSupervisor.mFocusedStack;

    //stack.getResumedActivity()表示當前處於resume狀態的Activity,即當前正在顯示的Activity,由於是從Launcher啓動一個程序的,
    //此時該程序還沒有啓動,這裏stack.getResumedActivity()依然是Launcher
    if (voiceSession == null && (stack.getResumedActivity() == null
            || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {//不成立
        //如果沒有當前正在顯示的Activity,有理由懷疑發起startActivity的進程此時是否能夠切換Activity;
        //這種情況通常發生在startActivity發起方進入pause/stop/destroy方法時,此時要暫停切換Activity
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                realCallingPid, realCallingUid, "Activity start")) {
            //如果沒有權限,則將啓動請求存入mPendingActivityLaunches後返回
            mController.addPendingActivityLaunch(new PendingActivityLaunch(r, sourceRecord, startFlags, stack, callerApp));
            ActivityOptions.abort(checkedOptions);
            return ActivityManager.START_SWITCHES_CANCELED;
        }
    }

    //mDidAppSwitch爲true
    if (mService.mDidAppSwitch) {
        mService.mAppSwitchesAllowedTime = 0;
    } else {
        mService.mDidAppSwitch = true;
    }

    /*啓動 mPendingActivityLaunches中存儲的待啓動Activity*/
    mController.doPendingActivityLaunches(false);

    //繼續調用startActivity()方法
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
    int result = START_CANCELED;
    try {
        mService.mWindowManager.deferSurfaceLayout();
        //調用startActivityUnchecked()方法
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity);
    } finally {
        final ActivityStack stack = mStartActivity.getStack();
        if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
            stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                    null /* intentResultData */, "startActivity", true /* oomAdj */);
        }
        mService.mWindowManager.continueSurfaceLayout();
    }

    //startActivityUnchecked結束後,做最後的Settings啓動處理
    postStartActivityProcessing(r, result, mTargetStack);

    return result;
}

點評:ProcessRecord維護一個activities的列表,用於存儲運行在該進程的Activity的ActivityRecord,比如com.android.launcher2.Launcher。應用程序本身都在AMS的管理範圍中,對於由應用程序 發起的startActivity,都可以在AMS中找到其對應的ProcessRecord,這樣可以確保調用方的權限匹配正確;

上述代碼的工作可以歸納如下:

①各種檢查:檢查調用方的權限、檢查調用方是否需要返回結果、檢查FLAG_ACTIVITY_FORWARD_RESULT標記、檢查Intent是否正確、檢查目標Activity是否存在、檢查是否有startActivity權限、檢查當前能否切換Activity;

②檢查通過後,創建目標Activity的ActivityRecord;

③將請求轉發給startActivityUncheckedLocked方法,此時處於mPendingActivityLaunches列表中的待啓動Activity將被優先處理。

由此可見,startActivityUncheckedLocked方法簽名中Unchecked的意思是:經過這麼多檢查(check),終於不需要檢查(uncheck)了。

 

繼續來看startActivityUncheckedLocked()方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {

    //初始化ActivityStarter的狀態,如mLaunchMode ,mLaunchFlags ,並且處理一些intent的常用標籤
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,voiceInteractor);

    //用來處理Settings的啓動模式,並將啓動方案添加在mLaunchFlags中
    computeLaunchingTaskFlags();

    //初始化mSourceStack,也就是Launcher的AcitivityStack
    computeSourceStack();

    .........
}

startActivityUncheckedLocked()的方法比較長,先看這幾個方法:

①setInitialState()

private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
        boolean doResume, int startFlags, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
    reset(false /* clearRequest */);

    mStartActivity = r;
    mIntent = r.intent;
    mOptions = options;
    mCallingUid = r.launchedFromUid;
    mSourceRecord = sourceRecord;
    mVoiceSession = voiceSession;
    mVoiceInteractor = voiceInteractor;

    mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);

    mLaunchParams.reset();

    mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
            options, mLaunchParams);

    //activity的啓動模式
    mLaunchMode = r.launchMode;

    mLaunchFlags = adjustLaunchFlagsToDocumentMode(
            r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
            LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
    mLaunchTaskBehind = r.mLaunchTaskBehind
            && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;

    sendNewTaskResultRequestIfNeeded();

    if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
        mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
    }

    if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        if (mLaunchTaskBehind
                || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
            mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
        }
    }

    //我們沒有設置FLAG_ACTIVITY_NO_USER_ACTION標籤,mSupervisor.mUserLeaving爲true
    mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
    if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
            "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);

    //doResume表示立刻啓動,我們傳進來的doResume爲true
    mDoResume = doResume;
    if (!doResume || !r.okToShowLocked()) {
        r.delayedResume = true;
        mDoResume = false;
    }

    //關於activity動畫的,先忽略
    if (mOptions != null) {
       ......
    }

    //沒有設置FLAG_ACTIVITY_PREVIOUS_IS_TOP標籤,所以mNotTop爲true
    mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;

    //目標Activity的TaskRecord,這裏爲null
    mInTask = inTask;

    if (inTask != null && !inTask.inRecents) {
        Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
        mInTask = null;
    }

    mStartFlags = startFlags;

    //未設置START_FLAG_ONLY_IF_NEEDED標籤
    if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
        ActivityRecord checkedCaller = sourceRecord;
        if (checkedCaller == null) {
            checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
                    mNotTop);
        }
        if (!checkedCaller.realActivity.equals(r.realActivity)) {
            // Caller is not the same as launcher, so always needed.
            mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
        }
    }

    //mNoAnimation爲false
    mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
}

 

點評:該方法是用來初始化ActivityStarter的狀態,如mLaunchMode ,mLaunchFlags ,並且處理intent的一些標籤,這些標籤常用的有:

FLAG_ACTIVITY_NO_USER_ACTION;

FLAG_ACTIVITY_PREVIOUS_IS_TOP;

FLAG_ACTIVITY_NO_ANIMATION;

我們來分析下FLAG_ACTIVITY_NO_USER_ACTION標籤,這個標籤有啥用呢?

它與Activity的生命週期有關,用於判斷是否是用戶行爲導致Activity切換。例如當用戶按Home鍵時,當前Activity切換到後臺,此時會回調當前Activity生命週期的onUserLeaveHint方法;但如果是來電導致當前Activity切換到後臺,則不會回調當前Activity生命週期的onUserLeaveHint方法。

若在啓動Activity的Intent中設置了FLAG_ACTIVITY_NO_USER_ACTION標記,則表明當前啓動行爲是非用戶行爲,這樣被切換到後臺的Activity便不會回調onUserLeaveHint方法。

②computeLaunchingTaskFlags()

private void computeLaunchingTaskFlags() {
    if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
        //由於mSourceRecord != null,這個判斷不成立,
        //不是由Activity發出的啓動請求,如系統啓動Launcher的過程-->mSourceRecord == null,
        ............
    } else {
        mInTask = null;
        if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
                && mSourceRecord.inFreeformWindowingMode())  {
            mAddingToTask = true;
        }
    }

    if (mInTask == null) {
        if (mSourceRecord == null) {//不成立
            if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
            //如果Launcher的啓動模式是SingleInstance,那就需要新建一個Task,本例中Launcher的啓動模式是SingleTask
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
            //如果Settings的啓動模式是SingleInstance或SingleTask,那就需要新建一個Task,本例中Settings的啓動模式是SingleTask
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        }
    }
}

點評:這個方法是用來處理Settings的啓動模式,並將啓動方案添加在mLaunchFlags中;

關於FLAG_ACTIVITY_NEW_TASK標籤,該標籤是用來確定待啓動Activity是否需要運行於新的Task;

需要在新的Task中運行Activity的條件有以下3種:

1)sourceRecord爲null,即不是由Activity發出的啓動請求,例如啓動Launcher或者通過adb start啓動指定Activity;

2)sourceRecord,也就是Launcher的啓動模式爲singleInstance;

3)要啓動的目標Activity,也就是Settings的啓動模式爲singleInstance或者singleTask。

其中,當3)中的Settings啓動模式爲singleTask時,如果Settings要運行的Task已經存在,那它就運行在那個已經創建出來的Task中,並不會重新創建一個新的Task;

③computeSourceStack()

初始化mSourceStack,也就是Launcher的ActivityStack;

 

繼續分析startActivityUncheckedLocked():

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {

    //初始化ActivityStarter的狀態,如mLaunchMode ,mLaunchFlags ,並且處理一些intent的常用標籤
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor);

    //用來處理Settings的啓動模式,並將啓動方案添加在mLaunchFlags中
    computeLaunchingTaskFlags();

    //初始化mSourceStack,也就是Launcher的AcitivityStack
    computeSourceStack();

    //將調整後的mLaunchFlags設置給mIntent
    mIntent.setFlags(mLaunchFlags);

    //查找是否有可複用的Task以及Activity,本例中的reusedActivity爲null,表示沒有可複用的Task以及Activity
    ActivityRecord reusedActivity = getReusableIntentActivity();

    ............
    ............

    //本例中的reusedActivity爲null
    if (reusedActivity != null) {
        //雖然本例中的reusedActivity爲null,但我們假設一下,reusedActivity爲true;
        if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
                (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
            Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }

        final boolean clearTopAndResetStandardLaunchMode =
                (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
                        == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
                && mLaunchMode == LAUNCH_MULTIPLE;//false

        //將可複用的棧賦給Settings,這樣他們就共處一個棧了
        if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {//成立
            mStartActivity.setTask(reusedActivity.getTask());
        }

        if (reusedActivity.getTask().intent == null) {
            reusedActivity.getTask().setIntent(mStartActivity);
        }

        if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                || isDocumentLaunchesIntoExisting(mLaunchFlags)
                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {//成立
            final TaskRecord task = reusedActivity.getTask();
            //在棧中尋找,Settings是否之前就已經存在於棧中,如果已經存在的話,就將此棧中在Settings之前的Activity全部從棧中移除,返回的top就是之前就已經存在於棧中的Settings;
            //現在Settings已經處於棧頂了
            final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                    mLaunchFlags);
            if (reusedActivity.getTask() == null) {
                reusedActivity.setTask(task);
            }

            if (top != null) {//成立
                if (top.frontOfTask) {
                    top.getTask().setIntent(mStartActivity);
                }
                //調用activity的onNewIntent()方法,這個屬於AMS與ActivityThread交互的範疇,暫時不討論
                deliverNewIntent(top);
            }
        }

        mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);

        reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);

        final ActivityRecord outResult =
                outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
        if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
            outActivity[0] = reusedActivity;
        }

        if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
            resumeTargetStackIfNeeded();
            return START_RETURN_INTENT_TO_CALLER;
        }

        if (reusedActivity != null) {
            setTaskFromIntentActivity(reusedActivity);

            if (!mAddingToTask && mReuseTask == null) {
                resumeTargetStackIfNeeded();
                if (outActivity != null && outActivity.length > 0) {
                    outActivity[0] = reusedActivity;
                }

                return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
            }
        }
    }
    ............
    ............
}

點評:我們再來看這部分代碼,這部分的代碼的意思是,檢查是否有可複用的Task或者Activity;

①通過getReusableIntentActivity()方法來檢查是否有可複用的Task或者Activity;

②如果有可複用的Task或者Activity,並且有下面3個啓動標籤中的一個:FLAG_ACTIVITY_CLEAR_TOP,LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK,那就在棧中尋找,Settings是否之前就已經存在於棧中,如果已經存在的話,就將Settings之前的Activity全部從棧中移除,並調用Settings的onNewIntent()方法;

由於getReusableIntentActivity()的代碼牽扯到affinity,所以我們得分析下它的代碼:

private ActivityRecord getReusableIntentActivity() {
    //本例的putIntoExistingTask 爲true
    boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
    putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;//成立,putIntoExistingTask爲true
    ActivityRecord intentActivity = null;
    if (mOptions != null && mOptions.getLaunchTaskId() != -1) {//不成立
        final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
        intentActivity = task != null ? task.getTopActivity() : null;
    } else if (putIntoExistingTask) {
        if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {//不成立
           intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                   mStartActivity.isActivityTypeHome());
        } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {//不成立
            intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                    !(LAUNCH_SINGLE_TASK == mLaunchMode));
        } else {//成立
            intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
        }
    }
    return intentActivity;
}

點評:從上面代碼可以看出,當滿足以下任何一個條件,需要判斷是否有可複用的Task:

1)在啓動標記中設置了FLAG_ACTIVITY_NEW_TASK且未設置FLAG_ACTIVITY_MULTIPLE_TASK;

 2)要啓動的目標Activity的啓動模式爲singleTask或者爲singleInstance;

可複用Task的匹配原則如下:

原則1:當要啓動的目標Activity的啓動模式非singleInstance時,遵循findTaskLocked方法的匹配規則;

原則2:當要啓動的目標Activity的啓動模式爲singleInstance時,遵循findActivityLocked方法的匹配 規則;

我們着重分析原則1,即mSupervisor.findTaskLocked()函數:

ActivityRecord findTaskLocked(ActivityRecord r, int displayId) {
    mTmpFindTaskResult.r = null;
    mTmpFindTaskResult.matchedByRootAffinity = false;
    ActivityRecord affinityMatch = null;
    //遍歷所有的顯示屏幕
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
        //遍歷屏幕裏所有的ActivityStack 
        for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = display.getChildAt(stackNdx);
            if (!r.hasCompatibleActivityType(stack)) {
                continue;
            }
            //調用ActivityStack.findTaskLocked(),返回結果在mTmpFindTaskResult中
            stack.findTaskLocked(r, mTmpFindTaskResult);
            if (mTmpFindTaskResult.r != null) {
                if (!mTmpFindTaskResult.matchedByRootAffinity) {
                    return mTmpFindTaskResult.r;
                } else if (mTmpFindTaskResult.r.getDisplayId() == displayId) {
                    affinityMatch = mTmpFindTaskResult.r;
                } else if (DEBUG_TASKS && mTmpFindTaskResult.matchedByRootAffinity) {
                }
            }
        }
    }
    return affinityMatch;
}

繼續看stack.findTaskLocked(r, mTmpFindTaskResult):

void findTaskLocked(ActivityRecord target, FindTaskResult result) {
        Intent intent = target.intent;
        ActivityInfo info = target.info;
        //獲取到ComponentName
        ComponentName cls = intent.getComponent();
        if (info.targetActivity != null) {
            cls = new ComponentName(info.packageName, info.targetActivity);
        }
        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
        boolean isDocument = intent != null & intent.isDocument();//isDocument爲false
        // If documentData is non-null then it must match the existing task data.
        Uri documentData = isDocument ? intent.getData() : null;//documentData爲null

        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + this);
        //遍歷ActivityStack中所有的TaskRecord
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            //得到task
            final TaskRecord task = mTaskHistory.get(taskNdx);
            if (task.voiceSession != null) {
                // We never match voice sessions; those always run independently.
                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
                continue;
            }
            if (task.userId != userId) {
                // Looking for a different task.
                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
                continue;
            }

            // Overlays should not be considered as the task's logical top activity.
            //從task的頂部開始尋找,找到第一個沒有被finish的ActivityRecord
            final ActivityRecord r = task.getTopActivity(false /* includeOverlays */);
            if (r == null || r.finishing || r.userId != userId ||
                    r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                continue;
            }
            if (!r.hasCompatibleActivityType(target)) {
                continue;
            }

            //得到Task的intent,taskIntent值得是啓動這個任務棧的intent
            final Intent taskIntent = task.intent;
            //得到Task的affinity
            final Intent affinityIntent = task.affinityIntent;
            final boolean taskIsDocument;
            final Uri taskDocumentData;
            if (taskIntent != null && taskIntent.isDocument()) {//不成立
                taskIsDocument = true;
                taskDocumentData = taskIntent.getData();
            } else if (affinityIntent != null && affinityIntent.isDocument()) {//不成立
                taskIsDocument = true;
                taskDocumentData = affinityIntent.getData();
            } else {//成立
                taskIsDocument = false;
                taskDocumentData = null;
            }

            if (taskIntent != null && taskIntent.getComponent() != null &&
                    taskIntent.getComponent().compareTo(cls) == 0 &&
                    Objects.equals(documentData, taskDocumentData)) {
                //查看Task的Intent是否與要啓動的目標Activity有相同的Component,如果有則返回該ActivityRecord
                result.r = r;
                result.matchedByRootAffinity = false;
                break;
            } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
                    affinityIntent.getComponent().compareTo(cls) == 0 &&
                    Objects.equals(documentData, taskDocumentData)) {
                //查看Task的affinityIntent是否與要啓動的目標Activity有相同的Component,如果有則返回該ActivityRecord
                result.r = r;
                result.matchedByRootAffinity = false;
                break;
            } else if (!isDocument && !taskIsDocument
                    && result.r == null && task.rootAffinity != null) {
                if (task.rootAffinity.equals(target.taskAffinity)) {
                    //Task的affinity是否與要啓動的目標Activity的affinity相同,如果有則返回該ActivityRecord
                    result.r = r;
                    result.matchedByRootAffinity = true;
                }
            } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
        }
    }

從上面可以總結下,可複用Task的匹配規則如下:

1)當要啓動的目標Activity的啓動模式非singleInstance 時:

遍歷mHistory中的ActivityRecord,查看該ActivityRecord所屬Task的affinity是否與要啓動的目標Activity的affinity相同,如果有則返回該ActivityRecord;

遍歷mHistory中的ActivityRecord,查看該ActivityRecord所屬Task的Intent是否與要啓動的目標Activity有相同的Component,如果有則返回該ActivityRecord;

遍歷mHistory中的ActivityRecord,查看該ActivityRecord所屬Task的affinityIntent是否與要啓動的目標Activity有相同的Component, 如果有則返回該ActivityRecord;

2)當要啓動的目標Activity的啓動模式爲singleInstance時:

遍歷mHistory中的ActivityRecord,查看該ActivityRecord所屬Task的Intent是否與要啓動的目標Activity有相同的Component,如果有則返回該ActivityRecord。

關於taskAffinity:我們可以在AndroidManifest.xml中設置android:taskAffinity,用來指定Activity希望歸屬的棧,在默認情況下,同一個應用程序的所有的Activity都有着相同的taskAffinity,taskAffinity在下面兩種情況下會產生效果:

1)taskAffinity與FLAG_ACTIVITY_NEW_TASK或者singleTask配合,如果新啓動的Activity的taskAffinity和棧的taskAffinity相同則加入到該棧;如果不同,就會創建新棧;

2)taskAffinity與allowTaskReparenting配合,如果allowTaskReparenting爲true,說明Activity具有轉移的能力;

 

接下來繼續分析startActivityUnchecked()的代碼:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    ............
    ............
    if (mStartActivity.packageName == null) {
        final ActivityStack sourceStack = mStartActivity.resultTo != null
                ? mStartActivity.resultTo.getStack() : null;
        if (sourceStack != null) {
            sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
                    mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
                    null /* data */);
        }
        ActivityOptions.abort(mOptions);
        return START_CLASS_NOT_FOUND;
    }

    //如果要啓動的目標Activity與當前棧頂正在顯示的Activity相同,需要檢查該Activity是否只需要啓動一次。
    //topStack是正在顯示的Activity棧
    final ActivityStack topStack = mSupervisor.mFocusedStack;
    final ActivityRecord topFocused = topStack.getTopActivity();
    //本例的top爲Launcher
    final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
    //要啓動的目標Activity與當前棧頂正在顯示的Activity相同,activity的啓動標籤爲FLAG_ACTIVITY_SINGLE_TOP或者啓動模式爲singTop與SingleTask之一;
    //滿足上述情況,dontStart就爲true,表示不需要重新啓動Activity,直接調用Activity的onNewActivity()方法即可
    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 & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
    if (dontStart) {//本例的dontStart爲false
        //我們假想,dontStart爲false
        topStack.mLastPausedActivity = null;
        if (mDoResume) {
            mSupervisor.resumeFocusedStackTopActivityLocked();
        }
        ActivityOptions.abort(mOptions);
        if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
            return START_RETURN_INTENT_TO_CALLER;
        }

        //調用activity的onNewActivity()方法,這是IPC部分的,後面分析
        deliverNewIntent(top);

        mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
                preferredLaunchDisplayId, topStack);

        return START_DELIVERED_TO_TOP;
    }

    ............
    ............
}

點評:startActivityUnchecked()方法執行到這裏,都是在判斷是否需要新啓動一個Task或者新啓動一個Activity,本例中我們是需要新啓動一個Task或者一個Activity的,那繼續看startActivityUnchecked()方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
............
............
    boolean newTask = false;
    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
            ? mSourceRecord.getTask() : null;

    int result = START_SUCCESS;
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {//條件成立
        newTask = true;
        //創建一個新的TaskRecord,並將新創建的TaskRecord與ActivityRecord進行關聯,即每個Activity會存儲其所處的Task
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
    } else if (mSourceRecord != null) {
        result = setTaskFromSourceRecord();
    } else if (mInTask != null) {
        result = setTaskFromInTask();
    } else {
        setTaskToCurrentTopOrCreateNewTask();
    }
    if (result != START_SUCCESS) {
        return result;
    }
    ............
    ............
}

點評:上面代碼的主要用途就是用來創建TaskRecord,來分析下setTaskFromReuseOrCreateNewTask()方法:

private int setTaskFromReuseOrCreateNewTask(
        TaskRecord taskToAffiliate, ActivityStack topStack) {
    //得到ActivityStack
    mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);

    if (mReuseTask == null) {//滿足
        //創建TaskRecord,其中taskId,就是TaskRecord的唯一標識符;
        //將ActivityStack與task進行綁定,並將task添加進mTaskHistory中
        final TaskRecord task = mTargetStack.createTaskRecord(
                mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
                mOptions);
        //綁定TaskRecord與ActivityRecord,並將ActivityRecord添加到TaskRecord的mActivities中
        addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
        updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);

    } else {
        addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
    }

    if (taskToAffiliate != null) {
        mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
    }

    if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
        return START_RETURN_LOCK_TASK_MODE_VIOLATION;
    }

    if (mDoResume) {//成立
        //該方法用於設置ActivityStack,TaskRecord的位置;
        //將當前的ActivityStack放到ActivityDisplay.mStacks的首位;
        //將當前的ActivityStack設爲mFocusedStack;
        //將當前的TaskRecord放到ActivityStack.mTaskHistory的首位;
        mTargetStack.moveToFront("reuseOrNewTask");
    }
    return START_SUCCESS;
}

點評:TaskRecord創建好了,相關的綁定操作也結束了,接下來繼續看startActivityUnchecked()方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    ............
    ............
    //權限控制
    mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
            mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
    mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
            mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
    if (newTask) {
        EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
                mStartActivity.getTask().taskId);
    }
    ActivityStack.logStartActivity(
            EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
    mTargetStack.mLastPausedActivity = null;

    mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);

    //調用mTargetStack.startActivityLocked,其中topFocused爲Launcher,newTask爲true
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    if (mDoResume) {//成立
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {//不成立
           
            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            mService.mWindowManager.executeAppTransition();
        } else {
            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            //調用resumeFocusedStackTopActivityLocked()
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else if (mStartActivity != null) {
        mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    }
    mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
            preferredLaunchDisplayId, mTargetStack);

    return START_SUCCESS;
}

點評:調用mSupervisor.resumeFocusedStackTopActivityLocked()方法,繼續執行;

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!readyToResume()) {
        return false;
    }

    if (targetStack != null && isFocusedStack(targetStack)) {//滿足
        //target爲mStartActivity
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || !r.isState(RESUMED)) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.isState(RESUMED)) {
        mFocusedStack.executeAppTransition(targetOptions);
    }

    return false;
}

調用:targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        //調用resumeTopActivityInnerLocked(),prev就是mStartActivity
        result = resumeTopActivityInnerLocked(prev, options);

        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
            checkReadyForSleep();
        }
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }

    return result;
}

接着看:resumeTopActivityInnerLocked(prev, options);

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }

    //取出第一個非finishing狀態的activity,本例中即Settings
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);

    final boolean hasRunningActivity = next != null;//hasRunningActivity爲true

    // TODO: Maybe this entire condition can get removed?
    if (hasRunningActivity && !isAttached()) {
        return false;
    }

    mStackSupervisor.cancelInitializingActivities();

    //記錄並重置userLeaving,本例爲true
    boolean userLeaving = mStackSupervisor.mUserLeaving;
    mStackSupervisor.mUserLeaving = false;

    if (!hasRunningActivity) {//不成立
        return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
    }

    //不延遲
    next.delayedResume = false;

    /*如果前端顯示的Activity就是當前要啓動的Activity,則直接返回。
    此時前端顯示的mResumedActivity仍然是Launcher,且處於Resume狀態,要啓動的next是Settings*/
    if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {//不成立
        executeAppTransition(options);
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Top activity resumed " + next);
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }

    ............
    .............

    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);

    boolean lastResumedCanPip = false;
    ActivityRecord lastResumed = null;
    final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
    if (lastFocusedStack != null && lastFocusedStack != this) {//不成立
        lastResumed = lastFocusedStack.mResumedActivity;
        if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
            userLeaving = false;
        }
        lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
                "resumeTopActivity", userLeaving /* beforeStopping */);
    }
    final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
            && !lastResumedCanPip;//resumeWhilePausing爲false

    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    /*啓動目標Activity前,需要首先暫停當前顯示的Activity。本例中,當前顯示的仍然爲Launcher*/
    if (mResumedActivity != null) {
        //首先暫停Launcher,這是我們遇到的第一個生命週期,next爲Settings
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    .........
    .........
    .........
}

點評:啓動Settings之前,需要先暫停Launcher,先看下startPausingLocked()函數;

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    //本例的mPausingActivity 暫時爲null,此時還沒確定需要暫停的Activity
    if (mPausingActivity != null) {//不成立
        if (!shouldSleepActivities()) {
            completePauseLocked(false, resuming);
        }
    }

    //本例中的prev是Launcher的ActivityRecord
    ActivityRecord prev = mResumedActivity;

    if (prev == null) {//不成立
        if (resuming == null) {
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
        }
        return false;
    }

    //resuming是Settings
    if (prev == resuming) {//不成立
        return false;
    }

    //設置當前要暫停的Activity爲Launcher
    mPausingActivity = prev;
    //設置上次暫停的Activity爲Launcher
    mLastPausedActivity = prev;
    mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
            || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
    //更改Launcher狀態爲正在暫停
    prev.setState(PAUSING, "startPausingLocked");
    prev.getTask().touchActiveTime();
    clearLaunchTime(prev);

    mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());

    mService.updateCpuStats();

    //prev.app就是ProcessRecord,本例中表示Launcher的進程;
    //prev.app.thread即IApplicationThread,可以訪問Launcher主線程
    if (prev.app != null && prev.app.thread != null) {//條件滿足
        try {
            mService.updateUsageStats(prev, false);

            //下面的代碼,就是暫停Launcher,這是AMS與ActivityThread交互的內容,暫時不討論
            //prev.appToken爲IApplicationToken.Stub,prev.finishing爲false,userLeaving爲true,異步執行
            mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                    PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
        } catch (Exception e) {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }
    } else {
        mPausingActivity = null;
        mLastPausedActivity = null;
        mLastNoHistoryActivity = null;
    }

    /*非休眠和關機狀態時,在Activity啓動前需要保持設備處於喚醒(awake)狀態*/
    if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
        mStackSupervisor.acquireLaunchWakelock();
    }

    //mPausingActivity爲Launcher
    if (mPausingActivity != null) {//成立
        if (!uiSleeping) {//成立
            //在新Activity啓動前,暫停key dispatch事件
            prev.pauseKeyDispatchingLocked();
        } else if (DEBUG_PAUSE) {
             Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
        }

        if (pauseImmediately) {//pauseImmediately爲false
            completePauseLocked(false, resuming);
            return false;

        } else {
            //暫停一個Activity也需要指定超時處理,防止無響應,在本例中執行以下代碼後返回
            schedulePauseTimeout(prev);
            return true;
        }

    } else {
        if (resuming == null) {
            //如果Pause操作失敗,只需要啓動棧頂Activity
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
        }
        return false;
    }
}

點評:①首先是AMS與ActivityThread進行交互,暫停Launcher,具體流程後面會詳細分析;

當Launcher調用了onPause()之後,會調用AMS的activityPaused()方法,進行下一步操作;

等會我們就要分析這個AMS的activityPaused()方法,AMS.activityPaused()最終會調用stack.activityPausedLocked()方法;

②暫停一個Activity需要指定超時處理,防止無響應,也就是調用schedulePauseTimeout(prev)方法,schedulePauseTimeout(prev)最終也會調用activityPausedLocked();

所以我們來看下activityPausedLocked():

final void activityPausedLocked(IBinder token, boolean timeout) {
    //此時的r爲Launcher
    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        //pause操作已經處理,移除之前添加的超時信息
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {//成立
            mService.mWindowManager.deferSurfaceLayout();
            try {
                //執行這一步
                completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
            } finally {
                mService.mWindowManager.continueSurfaceLayout();
            }
            return;
        } else {
            EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                    r.userId, System.identityHashCode(r), r.shortComponentName,
                    mPausingActivity != null
                        ? mPausingActivity.shortComponentName : "(none)");
            if (r.isState(PAUSING)) {
                if (r.finishing) {
                    finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false,
                            "activityPausedLocked");
                }
            }
        }
    }
    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}

執行completePauseLocked();

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    ActivityRecord prev = mPausingActivity;

    //本例的prev爲launcher
    if (prev != null) {
        prev.setWillCloseOrEnterPip(false);
        final boolean wasStopping = prev.isState(STOPPING);
        //切換Launcher的狀態爲PAUSED
        prev.setState(PAUSED, "completePausedLocked");
        //如果被暫停的Launcher處於finishing狀態,則destroy
        if (prev.finishing) {//不成立
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
                    "completedPausedLocked");
        } else if (prev.app != null) {//成立
            //等待新啓動Activity可見
            if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
                if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                        "Complete pause, no longer waiting: " + prev);
            }
            if (prev.deferRelaunchUntilPaused) {
                prev.relaunchActivityLocked(false /* andResume */,
                        prev.preserveWindowOnDeferredRelaunch);
            } else if (wasStopping) {
                prev.setState(STOPPING, "completePausedLocked");
            } else if (!prev.visible || shouldSleepOrShutDownActivities()) {                prev.setDeferHidingClient(false);
                //加入待stop列表,等着被stop
                addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
            }
        } else {
            prev = null;
        }
        if (prev != null) {
            prev.stopFreezingScreenLocked(true /*force*/);
        }
        //已經處理Pause操作,重置mPausingActivity
        mPausingActivity = null;
    }

    //非休眠或者準備關機狀態時,再次調用resumeFocusedStackTopActivityLocked
    if (resumeNext) {//成立
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!topStack.shouldSleepOrShutDownActivities()) {
            if (mService.mAppsLockOps != null) {

                ActivityRecord next = topStack.topRunningActivityLocked();
                if(DEBUG_APPLICATION_LOCK) {
                    Slog.v(TAG, "ApplicationLock in resumeNext: next = " + next.toString());
                }

                int result = 0;
                if (next != null) {
                    result = mService.mAppsLockOps.isPackageNeedLocked(next.packageName,
                            next.info.name, mService.isSleepingLocked(), next.userId);
                }

                if ((result != GomeApplicationsLockOps.APPLICATION_LOCK_DO_NOT_NEED_LOCK)) {
                    mService.showAccessInActivityThread(next, next.packageName,
                            next.userId);
                } else {
                    mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
                }

            } else {
                //調用resumeFocusedStackTopActivityLocked();
                //topStack是Settings的ActivityStack,prev爲Launcher
                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
            }
        } else {
            checkReadyForSleep();
            ActivityRecord top = topStack.topRunningActivityLocked();
            if (top == null || (prev != null && top != prev)) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
        }
    }

    //恢復接收WindowManagerService的Key Dispatch事件
    if (prev != null) {
        ............
        ............
    }

    if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
            || getDisplay().hasPinnedStack()) {
        mService.mTaskChangeNotificationController.notifyTaskStackChanged();
        mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
    }

    mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
}

點評:上述代碼有2個重要邏輯:

① addToStopping();

將Laucher加入到待stop列表,等着被stop,看下它的代碼:

void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
    if (!mStackSupervisor.mStoppingActivities.contains(r)) {
        //將Launcher添加進mStoppingActivities中,再Settings的onResume方法調用結束後,會調用Launcher的onStop方法
        mStackSupervisor.mStoppingActivities.add(r);
    }

    //stop列表中Activity數大於3時,發送並處理IDLE_NOW_MSG消息
    boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
            || (r.frontOfTask && mTaskHistory.size() <= 1);
    if (scheduleIdle || forceIdle) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
                + forceIdle + "immediate=" + !idleDelayed);
        if (!idleDelayed) {
            //發送IDLE_NOW_MSG消息,收到消息後調用activityIdleInternal()
            mStackSupervisor.scheduleIdleLocked();
        } else {
            mStackSupervisor.scheduleIdleTimeoutLocked(r);
        }
    } else {
        checkReadyForSleep();
    }
}

將Launcher添加進mStoppingActivities中後,調用mStackSupervisor.scheduleIdleLocked()發送IDLE_NOW_MSG消息,收到消息後調用activityIdleInternal(),關於activityIdleInternal()函數後面能看到,這裏先不分析;

②非休眠或者準備關機狀態時,再次調用mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null),最終會調用resumeTopActivityInnerLocked()方法;

繼續回到resumeTopActivityInnerLocked():

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ............
    ............
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    /*啓動目標Activity前,需要首先暫停當前顯示的Activity。本例中,當前顯示的仍然爲Launcher*/
    if (mResumedActivity != null) {
        //首先暫停Launcher,這是我們遇到的第一個生命週期
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }

    /// M: onBeforeActivitySwitch @{
    mService.mAmsExt.onBeforeActivitySwitch(mService.mLastResumedActivity, next, pausing,
            next.getActivityType());
    /// M: onBeforeActivitySwitch @}

    if (pausing && !resumeWhilePausing) {//不成立
        ............
............
        return true;
    } else if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {//不成立
      ............
        return true;
    }

    ............
    ............

    //perv是Settings,next也是Settings
    if (prev != null && prev != next) {//不成立
        if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
                && next != null && !next.nowVisible) {
            mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev);
        } else {
            //prev處於finish狀態時,需要立刻使其不可見,從而使新Activity立刻可見。prev處於非finish狀態時需要根據新Activity是否佔滿全屏決定prev是否可見
            if (prev.finishing) {
                prev.setVisibility(false);
            } else {
            }
        }
    }

    //確定應用程序非stop狀態
    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 to unstop package "
                + next.packageName + ": " + e);
    }
            ............
    boolean anim = true;
    if (prev != null) {
        if (prev.finishing) {//不滿足該分支
           ............
        } else {//滿足該分支
            ............
        }
    } else {
        //準備切換動畫
       ............
    }

    if (anim) {
        next.applyOptionsLocked();
    } else {
        next.clearOptionsLocked();//Options存儲切換動畫的信息,不需要動畫便清空
    }

    mStackSupervisor.mNoAnimActivities.clear();

    ActivityStack lastStack = mStackSupervisor.getLastStack();
    //next.app爲ProcessRecord,此時還未創建應用程序進程,因此爲null
    if (next.app != null && next.app.thread != null) {//不滿足
      .........
    } else {//滿足
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {//該Activity是否已經啓動過,此時爲false
            next.hasBeenLaunched = true;
        } else {//如果Activity已啓動,則直接執行restart
            if (SHOW_APP_STARTING_PREVIEW) {
                //顯示一個窗口前,先顯示一個過渡窗口
                next.showStartingWindow(null /* prev */, false /* newTask */,
                        false /* taskSwich */);
            }
        }
        //執行到這裏,終於要開始Settings的神奇啓動之旅了!
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

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

點評:走到了mStackSupervisor.startSpecificActivityLocked(next, true, true),終於要開始Settings的神奇啓動之旅了:

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    //獲取即將啓動的Activity的所在的應用程序進程,ProcessRecord將記錄Settings的進程信息,包括UID、進程名、UI主線程等
    //第一次啓動Activity,此時其應用程序進程還沒有創建,因此app爲null
    ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);

    getLaunchTimeTracker().setLaunchTime(r);

    //判斷要啓動的Acitivty所在的應用程序進程是否已經運行
    //startSpecificActivityLocked()方法會走兩次,第一次啓動的時候,不滿足下面的條件,第二次啓動的時候滿足
    if (app != null && app.thread != null) {
        try {
            //應用進程已經存在,則直接啓動Activity
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                        mService.mProcessStats);
            }
            //真正啓動Settings的邏輯在這裏
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
    }

    //否則,啓動應用程序進程,最終還是要執行realStartActivityLocked
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);
}

上面的代碼用於獲取Settings的進程,Settings此時還沒有進程,所以得給它創建一個進程mService.startProcessLocked(),由於創建進程的邏輯不是我們分析的關鍵點,所以就不詳細解釋了,看mService.startProcessLocked()代碼:

final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}


final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;
    if (!isolated) {
        //對於非isolated的app,需要從mProcessNames中查詢是否已經存在其進程信息
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
        checkTime(startTime, "startProcess: after getProcessRecord");

        if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
            if (mAppErrors.isBadProcessLocked(info)) {
                return null;
            }
        } else {
            mAppErrors.resetProcessCrashTimeLocked(info);
            if (mAppErrors.isBadProcessLocked(info)) {
                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
                        UserHandle.getUserId(info.uid), info.uid,
                        info.processName);
                mAppErrors.clearBadProcessLocked(info);
                if (app != null) {
                    app.bad = false;
                }
            }
        }
    } else {
     //對於isolated的app,不能複用已經存在的進程
     app = null;
    }

    /*在本例中,processName=com.android.settings,app=null,knownToBeDead=true,thread=null,pid=-1*/
    if (app != null && app.pid > 0) {//複用已有的進程
        if ((!knownToBeDead && !app.killed) || app.thread == null) {
            app.addPackage(info.packageName, info.versionCode, mProcessStats);
            checkTime(startTime, "startProcess: done, added package to proc");
            return app;
        }

        checkTime(startTime, "startProcess: bad proc running, killing");
        killProcessGroup(app.uid, app.pid);
        handleAppDiedLocked(app, true, true);
        checkTime(startTime, "startProcess: done killing old proc");
    }

    //hostingName表示運行於該進程的組件類型,本例中爲Activity
    String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null;

    if (app == null) {
        checkTime(startTime, "startProcess: creating new process record");
     //創建一個新的ProcessRecord
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        if (app == null) {
            return null;
        }
        app.crashHandler = crashHandler;
        app.isolatedEntryPoint = entryPoint;
        app.isolatedEntryPointArgs = entryPointArgs;
        checkTime(startTime, "startProcess: done creating new process record");
    } else {
        app.addPackage(info.packageName, info.versionCode, mProcessStats);
        checkTime(startTime, "startProcess: added package to existing proc");
    }

    /*mProcessesReady是在ActivityManagerService的systemReady執行完程序升級後,賦值爲true的。 該值表明此時系統進入可以真正啓動應用程序的階段'
 如果還沒有進入此狀態,需要先將啓動的應用進程加入mProcessesOnHold列表中等待*/
    if (!mProcessesReady
            && !isAllowedWhileBooting(info)
            && !allowWhileBooting) {
        if (!mProcessesOnHold.contains(app)) {
            mProcessesOnHold.add(app);
        }
        checkTime(startTime, "startProcess: returning with proc on hold");
        return app;
    }

    checkTime(startTime, "startProcess: stepping in to startProcess");
    //調用重載方法startProcessLocked(ProcessRecord app,……)
    final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
    checkTime(startTime, "startProcess: done starting proc!");
    return success ? app : null;
}

繼續調用startProcessLocked():

private final boolean startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
    if (app.pendingStart) {
        return true;
    }
    long startTime = SystemClock.elapsedRealtime();
    /*如果已經指定了PID且非當前進程的PID,需要從已有記錄中刪除,本例app.pid未分配,值爲0;MY_PID是system_server的進程ID*/
    if (app.pid > 0 && app.pid != MY_PID) {
        ............
    }

    //從mProcessesOnHold列表中刪除等待的ProcessRecord
    mProcessesOnHold.remove(app);

    checkTime(startTime, "startProcess: starting to update cpu stats");
    updateCpuStats();
    checkTime(startTime, "startProcess: done updating cpu stats");

    try {
        ............
        if (!app.isolated) {
            int[] permGids = null;
            try {
                checkTime(startTime, "startProcess: getting gids from package manager");
                final IPackageManager pm = AppGlobals.getPackageManager();
                // 通過PackageManagerService獲取應用程序組ID
                permGids = pm.getPackageGids(app.info.packageName,
                        MATCH_DEBUG_TRIAGED_MISSING, app.userId);
                StorageManagerInternal storageManagerInternal = LocalServices.getService(
                        StorageManagerInternal.class);
                mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
                        app.info.packageName);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }
            ............

        //調用startProcessLocked方法
        return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                startTime);
    } catch (RuntimeException e) {
        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
                false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
        return false;
    }
}

繼續調用startProcessLocked():

private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    .........
    if (mConstants.FLAG_PROCESS_START_ASYNC) {
        mProcStartHandler.post(() -> {
            try {
                synchronized (ActivityManagerService.this) {
                   ............
                }
                //startProcess--->Process.start()方法fork出一個子進程
                final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
                        app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
                        requiredAbi, instructionSet, invokeWith, app.startTime);
                synchronized (ActivityManagerService.this) {
                    //打印log,發送超時通知等
                    handleProcessStartedLocked(app, startResult, startSeq);
                }
            } catch (RuntimeException e) {
                ............
            }
        });
        return true;
    } else {
        ............
        return app.pid > 0;
    }
}

調用startProcess()方法fork出一個子進程:

private ProcessStartResult startProcess(String hostingType, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    try {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                app.processName);
        checkTime(startTime, "startProcess: asking zygote to start proc");
        final ProcessStartResult startResult;
        if (hostingType.equals("webview_service")) {
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        } else {
         // 設置Zygote調試標記,會讀取屬性配置
         /*通過zygote啓動一個新的進程。其本質仍然是fork出一個子進程,然後在子進程中
執行android.app.ActivityThread類的main方法,關於ActivityThread.main()屬於IPC部分的,後面在分析*/
         startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        }
        checkTime(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

點評:當Settings進程被fork出來後,就會調用該進程中的ActivityThread.main()方法,在ActivityThread.main()中,會創建進程的ActivityThread以及ApplicationThread,並調用它的ActivityThread.attach(),在該方法中,會調用AMS.attachApplication()方法,由於這個過程屬於AMS與ActivityThread交互部分,暫時不討論,我們先分析AMS.attachApplication()方法:

public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        //調用attachApplicationLocked(),thread就是Settings的ApplicationTread
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

繼續看attachApplicationLocked():

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {

    ProcessRecord app;
    long startTime = SystemClock.uptimeMillis();
    //傳入的PID是Settings的PID,而MY_PID代表system_process
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            //根據PID查找當前正在運行的應用程序對應的ProcessRecord
            app = mPidsSelfLocked.get(pid);
        }
    } else {
        app = null;
    }

    if (app == null && startSeq > 0) {//不成立
        ............
    }

    /*應用程序在執行attach方法之前,都會在ActivityManagerService中有對應的ProcessRecord,如果沒有,說明出現問題,需要殺死該進程*/
    if (app == null) {//不成立
        ............
    }

    ............

    final String processName = app.processName;
    try {
        //通過AppDeathRecipient監控進程退出
        AppDeathRecipient adr = new AppDeathRecipient(
                app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);
        app.deathRecipient = adr;
    } catch (RemoteException e) {
        app.resetPackageList(mProcessStats);
        startProcessLocked(app, "link fail", processName);
        return false;
    }

    EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);

    //將ApplicationThread與ProcessRecord綁定
    app.makeActive(thread, mProcessStats);
    //設置進程的OOM adj、線程組等信息
    app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;

    ............

    //啓動應用程序進程已完成,從消息隊列中移除在調用attach方法之前設置的超時信息
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
    //通過PackageManagerService獲取該應用程序中定義的ContentProvider
    List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
    try {
        ...........
       
        if (app.isolatedEntryPoint != null) {
            thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
        } else if (app.instr != null) {//成立
            //關鍵點在這,調用ActivityThread的bindApplication方法
            thread.bindApplication(processName, appInfo, providers,
                    app.instr.mClass,
                    profilerInfo, app.instr.mArguments,
                    app.instr.mWatcher,
                    app.instr.mUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial, isAutofillCompatEnabled);
        } else {
            ............
        }
        ............
    } catch (Exception e) {
        ............
    }

    ............

    if (normalMode) {
        try {
         //執行完ActivityThread.bindApplication,接下來執行mStackSupervisor.attachApplicationLocked();
         //主要功能是加載Activity,並執行其生命週期的onCreate、onStart、onResume等方法,最終顯示Activity。
         if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
           ............
        }
    }

    // Find any services that should be running in this process...
    //執行因爲等待進程創建而暫時掛起的Services
    if (!badApp) {
        ............
    }

    //發送因爲等待進程創建而暫時掛起的廣播
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        ............
    }

    ............

    if (!didSomething) {
        //執行了以上啓動組件的操作,需要調整OOM adj
        updateOomAdjLocked();
        checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
    }
    return true;
}

點評:上述代碼有兩塊比較重要的內容,

①thread.bindApplication();

ActivityThread的bindApplication()方法,主要是在ActivityThread中初始化應用程序的Context,初始化Instrumentation,創建應用程序的Application,調用Application的onCreate方法等,後面會詳細分析;

②mStackSupervisor.attachApplicationLocked(app);

主要功能是加載Activity,並執行其生命週期的onCreate、onStart、onResume等方法,最終顯示Activity;

主要來分析mStackSupervisor.attachApplicationLocked(app):

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
        for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = display.getChildAt(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
                        //調用realStartActivityLocked()
                        if (realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                                + top.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

繼續調用realStartActivityLocked():

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {

    ............

    try {
        /*當Activity attach到Application,並且應用進程沒有異常狀態(crash,ANR)時,需要通過WindowManagerService凍結屏幕並設置Activity可見*/
        r.startFreezingScreenLocked(app, 0);

        // schedule launch ticks to collect information about slow apps.
        r.startLaunchTickingLocked();

        //在ActivityRecord中記錄ProcessRecord,即Activity需要保存其運行進程的信息
        r.setProcess(app);

        ............

        final int applicationInfoUid =
                (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
        if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) {
        }

        app.waitingToKill = null;
        r.launchCount++;
        r.lastLaunchTime = SystemClock.uptimeMillis();

        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);

        //在ProcessRecord中記錄ActivityRecord,一個進程可以運行多個Activity
        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        
        //更新LRU
        mService.updateLruProcessLocked(app, true, null);
        mService.mHandler.post(mService::updateOomAdj);

        final LockTaskController lockTaskController = mService.getLockTaskController();
        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
                || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
                || (task.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED
                        && lockTaskController.getLockTaskModeState()
                                == LOCK_TASK_MODE_LOCKED)) {
            lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */);
        }

        try {
            //此時已經創建應用程序主線程,這裏不爲null
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<ReferrerIntent> newIntents = null;
            if (andResume) {//本例爲true
                results = r.results;
                newIntents = r.newIntents;
            }
            EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId,
                    System.identityHashCode(r), task.taskId, r.shortComponentName);
                mService.mHomeProcess = task.mActivities.get(0).app;
            }

            ............

            // Create activity launch transaction.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                    r.appToken);
            //①先將LaunchActivityItem做爲Callback
            clientTransaction.addaddCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                    profilerInfo));

            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {//andResume爲true
                lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            //②再設置ResumeActivityItem
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            //scheduleTransaction會一次調用LaunchActivityItem和ResumeActivityItem的execute()方法,
            //接下來調用Activity生命週期,主要包括 onCreate、 onStart 和 onResume
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);

            ............

        } catch (RemoteException e) {
            ............
        }
    } finally {
        endDeferResume();
    }

    r.launchFailed = false;
    if (stack.updateLRUListLocked(r)) {
        Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
    }

    if (andResume && readyToResume()) {//andResume爲true
        //執行onResume後的處理,如設置ActivityRecord的state爲RESUMED
        stack.minimalResumeActivityLocked(r);
    } else {
        if (DEBUG_STATES) Slog.v(TAG_STATES,
                "Moving to PAUSED: " + r + " (starting in paused state)");
        r.setState(PAUSED, "realStartActivityLocked");
    }

    if (isFocusedStack(stack)) {
        //系統升級時或第一次啓動時需要運行Setup Wizard
        mService.getActivityStartController().startSetupActivity();
    }

    if (r.app != null) {
        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
    }

    return true;
}

上述代碼中:

①LaunchActivityItem:

它對應着ActivityThread的handleLaunchActivity(),主要是調用Activity.attach()方法初始化Activity,後面會詳細分析;

②ResumeActivityItem:

它對應着Activity的生命週期,主要包括 onCreate、onStart和onResume,後面會詳細分析;

 

後面在分析ResumeActivityItem的時候,看到在ActivityThread.handleResumeActivity()中有這麼一句代碼:

Looper.myQueue().addIdleHandler(new Idler());

Activity在onResume後就進入了Idle狀態,此時將向主線程的消息隊列註冊IdleHandler,它會調用AMS.activityIdle()方法;

因爲這個代碼跟Launcher的stop有關,我們來分析下它的流程:

public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
    final long origId = Binder.clearCallingIdentity();
    synchronized (this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            //調用mStackSupervisor.activityIdleInternalLocked()
            ActivityRecord r =
                    mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
                            false /* processPausingActivities */, config);
            if (stopProfiling) {
                if ((mProfileProc == r.app) && mProfilerInfo != null) {
                    clearProfilerLocked();
                }
            }
            /// M: DuraSpeed
            mAmsExt.onEndOfActivityIdle(mContext, r.intent);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

繼續看:

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
        boolean processPausingActivities, Configuration config) {
    if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);

    ArrayList<ActivityRecord> finishes = null;
    ArrayList<UserState> startingUsers = null;
    int NS = 0;
    int NF = 0;
    boolean booting = false;
    boolean activityRemoved = false;

    ActivityRecord r = ActivityRecord.forTokenLocked(token);
    if (r != null) {
        //從ActivityStack的消息隊列中移除IDLE_TIMEOUT_MSG消息
        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
        r.finishLaunchTickingLocked();
        if (fromTimeout) {//不成立
            reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
        }
 
       ............

    }

    ............

    // Atomically retrieve all of the other things to do.
    /*獲取mStoppingActivities中存儲的待停止的Activity,暫停階段由completePauseLocked方法將源Activity存入該列表*/
    final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
            true /* remove */, processPausingActivities);
    NS = stops != null ? stops.size() : 0;
    if ((NF = mFinishingActivities.size()) > 0) {
        finishes = new ArrayList<>(mFinishingActivities);
        mFinishingActivities.clear();
    }

    if (mStartingUsers.size() > 0) {
        startingUsers = new ArrayList<>(mStartingUsers);
        mStartingUsers.clear();
    }

    //啓動目標Activity會導致停止其他Activity,包括源Activity
    for (int i = 0; i < NS; i++) {
        r = stops.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) {
            if (r.finishing) {
                /*如果源Activity處於finishing狀態,需要調用其onDestroy方法,
通常發生在源Activity在onPause方法中調用了finish方法*/
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
                        "activityIdleInternalLocked");
            } else {
                //否則直接調用源Activity的onStop方法
                stack.stopActivityLocked(r);
            }
        }
    }

    //啓動目標Activity可能導致需要回收其他Activity
    for (int i = 0; i < NF; i++) {
        r = finishes.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) {
            activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
        }
    }

    if (!booting) {//本例的booting爲false
        // Complete user switch
        if (startingUsers != null) {
            for (int i = 0; i < startingUsers.size(); i++) {
                mService.mUserController.finishUserSwitch(startingUsers.get(i));
            }
        }
    }

    //回收應用程序進程,並更新OOM adj
    mService.trimApplications();
    //dump();
    //mWindowManager.dump();

    if (activityRemoved) {//本例爲false
        resumeFocusedStackTopActivityLocked();
    }

    return r;
}

點評:在之前的completePauseLocked()方法中我們就將待停止的Launcher添加進了mStoppingActivities中,現在就要開始調用Launcher的stop()方法了;

繼續看stack.stopActivityLocked(r):

final void stopActivityLocked(ActivityRecord r) {
   .............
    if (r.app != null && r.app.thread != null) {
        adjustFocusedActivityStack(r, "stopActivity");
        r.resumeKeyDispatchingLocked();
        try {
            r.stopped = false;
            if (DEBUG_STATES) Slog.v(TAG_STATES,
                    "Moving to STOPPING: " + r + " (stop requested)");
            //設置狀態
            r.setState(STOPPING, "stopActivityLocked");
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                    "Stopping visible=" + r.visible + " for " + r);
            if (!r.visible) {
                //設置可見性
                r.setVisible(false);
            }
            EventLogTags.writeAmStopActivity(
                    r.userId, System.identityHashCode(r), r.shortComponentName);
            //使用StopActivityItem,完成了Launcher的onStop()方法調用
            mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
                    StopActivityItem.obtain(r.visible, r.configChangeFlags));
            if (shouldSleepOrShutDownActivities()) {
                r.setSleeping(true);
            }
            Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
            mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
        } catch (Exception e) {
           ............
        }
    }
}

點評:修改Launcher的狀態,並且使用StopActivityItem,完成了Launcher的onStop()方法調用,後面會具體分析;

 

分析到了這裏,根Activity的啓動流程基本結束了,現在,Settings已經顯示出來,而Launcher正在stop狀態;

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章