淺談Activity啓動流程

概述

Activity的啓動方式有兩種,一種是顯式的,一種是隱式的。
而且,啓動的 Activity 和原 Activity 的進程關係的不同又可以分爲兩種情況,一種是在同一個進程,另外一種情況是開啓一個新的進程來啓動 Activity

Activity啓動之前的一些事情

  • init進程:init是所有linux程序的起點,是Zygote的父進程。解析init.rc孵化出Zygote進程。
  • Zygote進程:Zygote是所有Java進程的父進程,所有的App進程都是由Zygote進程fork生成的。
  • SystemServer進程:System Server是Zygote孵化的第一個進程。SystemServer負責啓動和管理整個Java framework,包含AMS,PMS等服務。
  • Launcher:Zygote進程孵化的第一個App進程是Launcher。

1.init進程是什麼?

Android是基於linux系統的,手機開機之後,linux內核進行加載。加載完成之後會啓動init進程。
init進程會啓動ServiceManager,孵化一些守護進程,並解析init.rc孵化Zygote進程。

2.Zygote進程是什麼?

所有的App進程都是由Zygote進程fork生成的,包括SystemServer進程。Zygote初始化後,會註冊一個等待接受消息的  socket,OS層會採用socket進行IPC通信。

3.爲什麼是Zygote來孵化進程,而不是新建進程呢?

每個應用程序都是運行在各自的Dalvik虛擬機中,應用程序每次運行都要重新初始化和啓動虛擬機,這個過程會耗費很長時間。Zygote會把已經運行的虛擬機的代碼和內存信息共享,起到一個預加載資源和類的作用,從而縮短啓動時間。

Activity啓動階段

涉及到的概念

  • 進程:Android系統爲每個APP分配至少一個進程
  • IPC:跨進程通信,Android中採用Binder機制。

涉及到的類

  • ActivityThread:代表了應用的主線程,在Activity.attach()方法中初始化
  • TaskRecord:Activity的管理者
  • ActivityStack:Stack的管理者
  • ActivityStackSupervisor:ActivityStack的管理者,早期的Android版本是沒有這個類的,直到Android 6.0纔出現。

涉及到的進程

  • Launcher所在的進程
  • AMS所在的SystemServer進程
  • 要啓動的Activity所在的app進程

如果是啓動根Activity,就涉及上述三個進程。
如果是啓動子Activity,那麼就只涉及AMS進程和app所在進程。

具體流程

  • Launcher:Launcher通知AMS要啓動activity。

startActivitySafely->startActivity->Instrumentation.execStartActivity()(AMP.startActivity)->AMS.startActivity

  • AMS:PMS的resoveIntent驗證要啓動activity是否匹配。

如果匹配,通過ApplicationThread發消息給Launcher所在的主線程,暫停當前Activity(Launcher);

  • 暫停完,在該activity還不可見時,通知AMS,根據要啓動的Activity配置ActivityStack。然後判斷要啓動的Activity進程是否存在?

存在:發送消息LAUNCH_ACTIVITY給需要啓動的Activity主線程,執行handleLaunchActivity

不存在:通過socket向zygote請求創建進程。進程啓動後,ActivityThread.attach

  • 判斷Application是否存在,若不存在,通過LoadApk.makeApplication創建一個。在主線程中通過thread.attach方法來關聯ApplicationThread。
  • 在通過ActivityStackSupervisor來獲取當前需要顯示的ActivityStack。
  • 繼續通過ApplicationThread來發送消息給主線程的Handler來啓動Activity(handleLaunchActivity)。
  • handleLauchActivity:調用了performLauchActivity,裏邊Instrumentation生成了新的activity對象,繼續調用activity生命週期。

IPC過程:

雙方都是通過對方的代理對象來進行通信。

  • 1.app和AMS通信:app通過本進程的AMP和AMS進行Binder通信
  • 2.AMS和新app通信:通過ApplicationThreadProxy來通信,並不直接和ActivityThread通信

Activity啓動流程(從Launcher開始):

第一階段: Launcher通知AMS要啓動新的Activity(在Launcher所在的進程執行)

  • Launcher.startActivitySafely //首先Launcher發起啓動Activity的請求
  • Activity.startActivity
    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }
  • Activity.startActivityForResult 
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
    // 一般情況下會走mParent == null分支
    if (mParent == null) {
        //調用Instrumentation.execStartActivity()啓動新的Activity。mMainThread類型爲ActivityThread, 在attach()函數被回調時被賦值。
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            // 如果activity之前已經啓動,而且處於阻塞狀態,execStartActivity函數直接返回要啓動的activity的result或者null。
            //如果結果不爲空,發送結果
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            // 如果需要一個返回結果,那麼賦值mStartedActivity爲true,在結果返回來之前保持當前Activity不可見
            mStartedActivity = true;
        }
        cancelInputsAndStartExitTransition(options);
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

這裏注意到 mParent 變量,一般情況下這裏 mParent 是爲空的,除非是啓動 ActivityGroup 等可以嵌套 Activity 的內部的 Activity 時纔會不爲空。 

  • Instrumentation.execStartActivity //交由Instrumentation代爲發起請求
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    // 判斷mActivityMonitors是否爲空,mActivityMonitors可以通過addMonitor()方法創建,一般在自動化測試時使用
    // 一般情況下不會走這個分支
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                if (am.match(who, null, intent)) {
                    am.mHits++;
                    // 如果處於阻塞狀態,直接返回
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
        // 這裏的ActivityManagerNative.getDefault返回ActivityManagerService的遠程接口,即ActivityManagerProxy接口
        // 由它通過進程間通信調用 AMS 的 startActivity 方法
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

mActivityMonitors 是 ActivityMonitor 的一個集合,該類用來監控應用中的單個活動,可監控一些指定的意圖。一般在一些測試Case時使用。創建 ActivityMonitor 實例後,通過調用 ActivityInstrumentationTestCase2 的 getInstrumentation() 方法獲取 Instrumentation 實例,然後通過 addMonitor 方法添加這個實例,當目標活動啓動後,系統會匹配 Instrumentation 中的 ActivityMonitor 實例列表,如果匹配,就會累加計數器。 

  • ActivityManager.getService().startActivity //通過IActivityManagerSingleton.get()得到一個AMP代理對象
  • ActivityManagerProxy.startActivity //通過AMP代理通知AMS啓動activity

第二階段:AMS先校驗一下Activity的正確性,如果正確的話,會暫存一下Activity的信息。然後,AMS會通知Launcher程序pause Activity(在AMS所在進程執行)

  • ActivityManagerService.startActivity
    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }
  • ActivityManagerService.startActivityAsUser
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
    enforceNotIsolatedCaller("startActivity");
    userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
            false, ALLOW_FULL_ONLY, "startActivity", null);
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, false, userId, null, null);
}

從這裏開始就在AMS進程中執行了,下面簡單介紹一下這些參數代表的意義:

resultTo: 指調用者Activity的mToken,mToken對象保存它所處的ActivityRecord信息

  • ActivityStackSupervisor.startActivityMayWait
final 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 config,
         Bundle options, boolean ignoreTargetSecurity, int userId,
         IActivityContainer iContainer, TaskRecord inTask) {
     // 不允許傳遞文件描述符
     if (intent != null && intent.hasFileDescriptors()) {
         throw new IllegalArgumentException("File descriptors passed in Intent");
     }
     boolean componentSpecified = intent.getComponent() != null;
     // 重新實例化一個Intent對象,防止對intent的修改
     intent = new Intent(intent);
     // 通過Intent解析Activity信息,最終會調用PackageManagerService.resolveIntent()來查詢和選擇相關的Activity
     // 如果有多個Activity匹配,那麼就會彈框讓用戶來選擇,這部分分析此處省略
     ActivityInfo aInfo =
             resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
     ActivityContainer container = (ActivityContainer)iContainer;
     synchronized (mService) {
         // 一般情況下container 爲null
         if (container != null && container.mParentActivity != null &&
                 container.mParentActivity.state != RESUMED) {
             return ActivityManager.START_CANCELED;
         }
         final int realCallingPid = Binder.getCallingPid();
         final int realCallingUid = Binder.getCallingUid();
         int callingPid;
         if (callingUid >= 0) {
             callingPid = -1;
         } else if (caller == null) {
             callingPid = realCallingPid;
             callingUid = realCallingUid;
         } else {
             callingPid = callingUid = -1;
         }
         final ActivityStack stack;
         if (container == null || container.mStack.isOnHomeDisplay()) {
             // 一般會走到這裏,將當前的ActivityStack賦值給stack
             stack = mFocusedStack;
         } else {
             stack = container.mStack;
         }
         stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
         final long origId = Binder.clearCallingIdentity();
         if (aInfo != null &&
                 (aInfo.applicationInfo.privateFlags
                         &ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
             // 處理heavy-weight process,即重量級進程,這種進程在內存不足時不會被kill掉
             // 一般不會走這裏
             if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                 if (mService.mHeavyWeightProcess != null &&
                         (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
                         !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
                     int appCallingUid = callingUid;
…………//此處代碼省略
                 }
             }
         }
         int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                 voiceSession, voiceInteractor, resultTo, resultWho,
                 requestCode, callingPid, callingUid, callingPackage,
                 realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                 componentSpecified, null, container, inTask);
         Binder.restoreCallingIdentity(origId);
         if (stack.mConfigWillChange) {
             // 一般不會走這裏
             …………
         }
         if (outResult != null) {
             // 一般不會走這裏
             ……
         }
         return res;
     }
 }
  • ActivityStackSupervisor.startActivityLocked :檢查有沒有在AndroidManifest中註冊
final int startActivityLocked(IApplicationThread caller,
        Intent intent, String resolvedType, ActivityInfo aInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode,
        int callingPid, int callingUid, String callingPackage,
        int realCallingPid, int realCallingUid, int startFlags, Bundle options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        ActivityContainer container, TaskRecord inTask) {
    int err = ActivityManager.START_SUCCESS;
    ProcessRecord callerApp = null;
    if (caller != null) {
        // 獲取調用者所在的ProcessRecord
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    // 獲取userId,如果是管理員用戶該值爲0
    final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
    if (err == ActivityManager.START_SUCCESS) {
        // 打印一些信息
    }
    ActivityRecord sourceRecord = null;
    ActivityRecord resultRecord = null;
    // resultTo爲調用者Activity的mToken,保存了它所處的ActivityRecord信息
    if (resultTo != null) {
        // 獲取調用者Activity所對用的ActivityRecord
        sourceRecord = isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {
            // 如果需要返回結果,即requestCode不爲-1,賦值resultRecord
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
    final int launchFlags = intent.getFlags();
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        // 對Intent.FLAG_ACTIVITY_FORWARD_RESULT處理,如果設置了這個flag,執行結果相當於透傳
        // 比如Activity啓動順序A->B->C,那麼C的結果將直接返回給A
        …………//此處代碼忽略
    }
    if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
        err = ActivityManager.START_INTENT_NOT_RESOLVED;
    }
    if (err == ActivityManager.START_SUCCESS && aInfo == null) {
        // 如果待啓動的Activity沒有在Manifestfest中顯示聲明,就會有這個error
        err = ActivityManager.START_CLASS_NOT_FOUND;
    }
    if (err == ActivityManager.START_SUCCESS
            && !isCurrentProfileLocked(userId)
            && (aInfo.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
        err = ActivityManager.START_NOT_CURRENT_USER_ACTIVITY;
    }
    if (err == ActivityManager.START_SUCCESS && sourceRecord != null
            && sourceRecord.task.voiceSession != null) {
        ……
    }
    if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
        ……
    }
    final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
    if (err != ActivityManager.START_SUCCESS) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1,
                resultRecord, resultWho, requestCode,
                Activity.RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return err;
    }
    boolean abort = false;
    final int startAnyPerm = mService.checkPermission(
            START_ANY_ACTIVITY, callingPid, callingUid);
    執行一系列的權限檢查
    …………
    abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
            callingPid, resolvedType, aInfo.applicationInfo);
    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();
            abort |= !mService.mController.activityStarting(watchIntent,
                    aInfo.applicationInfo.packageName);
        } catch (RemoteException e) {
            mService.mController = null;
        }
    }
    if (abort) {
        // 權限檢查不通過就退出
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                    Activity.RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return ActivityManager.START_SUCCESS;
    }
    // 新建一個ActivityRecord,對應將要啓動的Activity
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, voiceSession != null, this, container, options);
    if (outActivity != null) {
        outActivity[0] = r;
    }
    if (r.appTimeTracker == null && sourceRecord != null) {
        r.appTimeTracker = sourceRecord.appTimeTracker;
    }
    // 當前的ActivityStack
    final ActivityStack stack = mFocusedStack;
    if (voiceSession == null && (stack.mResumedActivity == null
            || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                realCallingPid, realCallingUid, "Activity start")) {
            PendingActivityLaunch pal =
                    new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
            mPendingActivityLaunches.add(pal);
            ActivityOptions.abort(options);
            return ActivityManager.START_SWITCHES_CANCELED;
        }
    }
    if (mService.mDidAppSwitch) {
        mService.mAppSwitchesAllowedTime = 0;
    } else {
        mService.mDidAppSwitch = true;
    }
    doPendingActivityLaunchesLocked(false);
    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);
    if (err < 0) {
        notifyActivityDrawnForKeyguard();
    }
    return err;
}
  • ActivityStackSupervisor.startActivityUncheckedLocked

參數中 r 代表即將要啓動的 Activity 對應的 ActivityRecordsourceRecord 代表調用者。

final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
        boolean doResume, Bundle options, TaskRecord inTask) {
    final Intent intent = r.intent;
    final int callingUid = r.launchedFromUid;
    // 如果指定的inTask不在Recents列表中,認爲inTask是無效的
    // inTask不爲空,表示調用者希望在指定的task裏面啓動activity
    // 一般情況下爲null
    if (inTask != null && !inTask.inRecents) {
        inTask = null;
    }
    // 被啓動Activity的啓動模式
    final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
    final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
    final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
    int launchFlags = intent.getFlags();
    if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
            (launchSingleInstance || launchSingleTask)) {
        //當Inent中定義的launch flag和manifest中定義的有衝突的話優先使用manifest中定義的
        launchFlags &=
                ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
    } else {
        switch (r.info.documentLaunchMode) {
            case ActivityInfo.DOCUMENT_LAUNCH_NONE:
                break;
            case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
                break;
            case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
                break;
            case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
                launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
                break;
        }
    }
    // 是否爲後臺啓動任務的標誌位
    final boolean launchTaskBehind = r.mLaunchTaskBehind
            && !launchSingleTask && !launchSingleInstance
            && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
    if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0
            && r.resultTo.task.stack != null) {
        // 如果需要返回結果,但是此時的launchFlags有FLAG_ACTIVITY_NEW_TASK,則取消返回結果
        r.resultTo.task.stack.sendActivityResultLocked(-1,
                r.resultTo, r.resultWho, r.requestCode,
                Activity.RESULT_CANCELED, null);
        r.resultTo = null;
    }
    if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
        // 賦予FLAG_ACTIVITY_NEW_TASK標誌
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    }
    if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        // 如果設置了android:documentLaunchMode爲always,那麼設置FLAG_ACTIVITY_MULTIPLE_TASK標誌
        // 即使在其他task裏面有該Activity以及啓動,仍然新建Task再次啓動一個Activity
        if (launchTaskBehind
                || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
            launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
        }
    }
    // 判斷一下是否是用戶的行爲,比如用戶按下Home鍵等等
    // 如果是用戶的行爲的話Activity跳轉的時候是要調用onUserLeaveHint()方法的
    mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
    // 如果設置了不需要resume,那麼設置延遲resume標誌
    if (!doResume) {
        r.delayedResume = true;
    }
    // FLAG_ACTIVITY_PREVIOUS_IS_TOP標誌來決定待啓動Activity會不會被作爲棧頂,
    // 如果調用者希望待啓動的Activity馬上銷燬,就會使用該啓動參數。
    // 通常情況下notTop爲null
    ActivityRecord notTop =
            (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
        ActivityRecord checkedCaller = sourceRecord;
        if (checkedCaller == null) {
            checkedCaller = mFocusedStack.topRunningNonDelayedActivityLocked(notTop);
        }
        if (!checkedCaller.realActivity.equals(r.realActivity)) {
            // 如果調用者和被調用者不是同一個Activity,去掉這個標誌,因爲這個時候都需要啓動
            startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
        }
    }
    boolean addingToTask = false;//表示是否需要在inTask中啓動activity
    TaskRecord reuseTask = null;//表示可以複用的task
    //當調用者不是來自activity,而是明確指定task的情況。
    if (sourceRecord == null && inTask != null && inTask.stack != null) {
        final Intent baseIntent = inTask.getBaseIntent();
        final ActivityRecord root = inTask.getRootActivity();
        
        ……
        if (root == null) {
            // 如果inTask是個空的task,從baseIntent裏面挑選出一些flag設置到launchFlags
            final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
                    | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
            launchFlags = (launchFlags&~flagsOfInterest)
                    | (baseIntent.getFlags()&flagsOfInterest);
            intent.setFlags(launchFlags);
            inTask.setIntent(r);
            addingToTask = true;
        } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            // 如果inTask非空,launchFlags要求在新task裏面啓動那麼就不加入到這個task裏面去
            addingToTask = false;
        } else {
            // 其他情況就加入到inTask
            addingToTask = true;
        }
        // 如果inTask不爲空,就作爲複用的task
        reuseTask = inTask;
    } else {
        inTask = null;
    }
    if (inTask == null) {
        // 當沒有指定task
        if (sourceRecord == null) {
            // 調用者不是一個activity,那麼就在一個新的task裏面啓動activity
            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            }
        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
            // 如果調用者是一個activity,而且調用者的啓動模式是LAUNCH_SINGLE_INSTANCE,
            // 那麼也需要在新的task裏面啓動
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        } else if (launchSingleInstance || launchSingleTask) {
            // 啓動標誌位裏面是SingleInstance或者launchSingleTask,也需要在新task裏面啓動
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        }
    }
    ActivityInfo newTaskInfo = null;
    Intent newTaskIntent = null;
    ActivityStack sourceStack;
    if (sourceRecord != null) {
        if (sourceRecord.finishing) {
            // 如果調用者activity處於正在銷燬的狀態,那麼就需要在新的task裏啓動
            // 並且保存一些調用者的信息,並把sourceRecord和sourceStack置空
            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                newTaskInfo = sourceRecord.info;
                newTaskIntent = sourceRecord.task.intent;
            }
            sourceRecord = null;
            sourceStack = null;
        } else {
            // 如果不在銷燬狀態,把其所在的棧賦於sourceStack
            sourceStack = sourceRecord.task.stack;
        }
    } else {
        sourceStack = null;
    }
    boolean movedHome = false;
    ActivityStack targetStack;
    // 至此,啓動參數的修正工作結束,設置給intent
    intent.setFlags(launchFlags);
    // 看是否需要動畫
    final boolean noAnimation = (launchFlags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0;
    // FLAG_ACTIVITY_NEW_TASK && FLAG_ACTIVITY_MULTIPLE_TASK 表示不是在當前任務中啓動,
    // 但是要查看是否有目標Activity已經存在的任務,同launchSingleInstance和launchSingleTask
    if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || launchSingleInstance || launchSingleTask) {
        if (inTask == null && r.resultTo == null) {
            // 在沒有指定task且不要返回結果的情況下,去查找是否有匹配的activity
            // findTaskLocked是找到匹配的目標ActivityRecord所在的任務棧(TaskRecord),包含taskAffinity的操作
            // 這個方法後面會詳細介紹
            // 從棧頂至棧底遍歷ActivityStack中的所有Activity,根據Intent和ActivityInfo這
            // 兩個參數得到的Activity的包名
            ActivityRecord intentActivity = !launchSingleInstance ?
                    findTaskLocked(r) : findActivityLocked(intent, r.info);
            if (intentActivity != null) {
                // intentActivity不爲空表示找到目標activity,那麼目標Activity所在的任務(TaskRecord)
                // 和任務所在的棧(ActivityRecord)就是宿主任務和宿主棧
                // 這裏通過isLockTaskModeViolation鎖定屏幕的那些Task
                if (isLockTaskModeViolation(intentActivity.task,
                        (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
                    // 如果不是鎖定的task,就結束啓動流程
                    // lock task mode 是Android 5.0 Lollipop添加的功能
                    showLockTaskToast();
                    return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
                }
                if (r.task == null) {
                    r.task = intentActivity.task;
                }
                if (intentActivity.task.intent == null) {
                    intentActivity.task.setIntent(r);
                }
                targetStack = intentActivity.task.stack;
                targetStack.mLastPausedActivity = null;
                // 如果目標task不在前臺就需要把它移至前臺
                // 這裏首先獲取焦點所在的棧
                final ActivityStack focusStack = getFocusedStack();
                //從焦點棧裏面找到當前可見的ActivityRecord
                ActivityRecord curTop = (focusStack == null)
                        ? null : focusStack.topRunningNonDelayedActivityLocked(notTop);
                boolean movedToFront = false;
                if (curTop != null && (curTop.task != intentActivity.task ||
                        curTop.task != focusStack.topTask())) {
                    // 滿足上面的條件表示待啓動的activity和當前可見activity不在同一個task
                    // 那麼就需要將待啓動的activity所在的棧移動到前臺
                    r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
                    if (sourceRecord == null || (sourceStack.topActivity() != null &&
                            sourceStack.topActivity().task == sourceRecord.task)) {
                        if (launchTaskBehind && sourceRecord != null) {
                            intentActivity.setTaskToAffiliateWith(sourceRecord.task);
                        }
                        movedHome = true;
                        // 將目標任務移動到棧頂
                        targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
                                options, r.appTimeTracker, "bringingFoundTaskToFront");
                        movedToFront = true;
                        if ((launchFlags &
                                (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                                == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
                            //將toReturnTo設置爲home
                            intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                        }
                        options = null;
                    }
                }
                if (!movedToFront) {
                    // 將當前棧移動到前臺
                    targetStack.moveToFront("intentActivityFound");
                }
                // 根據需要重置activity所在的task
                if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                    intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
                }
                if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                    // 如果不需要啓動一個新的activity,結束啓動流程
                    if (doResume) {
                        resumeTopActivitiesLocked(targetStack, null, options);
                        // 如果沒有移動到前臺,通知Keyguard
                        if (!movedToFront) {
                            notifyActivityDrawnForKeyguard();
                        }
                    } else {
                        ActivityOptions.abort(options);
                    }
                    return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                }
                if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
                    // 這裏需要移除目標task中所有關聯的其他activity,即要完全替代目標task
                    // 將該啓動activity變爲task中的根activity
                    reuseTask = intentActivity.task;
                    reuseTask.performClearTaskLocked();
                    reuseTask.setIntent(r);
                } else if ((launchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                        || launchSingleInstance || launchSingleTask) {
                    // 清除task中目標activity上面的所有activity,返回目標activity
                    ActivityRecord top =
                            intentActivity.task.performClearTaskLocked(r, launchFlags);
                    if (top != null) {
                        if (top.frontOfTask) {
                            top.task.setIntent(r);
                        }
                        //觸發調用onNewIntent()
                        top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                    } else {
                        // A special case: we need to start the activity because it is not
                        // currently running, and the caller has asked to clear the current
                        // task to have this activity at the top.
                        addingToTask = true;
                        // Now pretend like this activity is being started by the top of its
                        // task, so it is put in the right place.
                        sourceRecord = intentActivity;
                        TaskRecord task = sourceRecord.task;
                        if (task != null && task.stack == null) {
                            // Target stack got cleared when we all activities were removed
                            // above. Go ahead and reset it.
                            targetStack = computeStackFocus(sourceRecord, false /* newTask */);
                            targetStack.addTask(
                                    task, !launchTaskBehind /* toTop */, false /* moving */);
                        }
                    }
                } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
                    // In this case the top activity on the task is the
                    // same as the one being launched, so we take that
                    // as a request to bring the task to the foreground.
                    // If the top activity in the task is the root
                    // activity, deliver this new intent to it if it
                    // desires.
                    if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
                            && intentActivity.realActivity.equals(r.realActivity)) {
                        ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
                                intentActivity.task);
                        if (intentActivity.frontOfTask) {
                            intentActivity.task.setIntent(r);
                        }
                        intentActivity.deliverNewIntentLocked(callingUid, r.intent,
                                r.launchedFromPackage);
                    } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
                        // In this case we are launching the root activity
                        // of the task, but with a different intent.  We
                        // should start a new instance on top.
                        addingToTask = true;
                        sourceRecord = intentActivity;
                    }
                } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
                    // In this case an activity is being launched in to an
                    // existing task, without resetting that task.  This
                    // is typically the situation of launching an activity
                    // from a notification or shortcut.  We want to place
                    // the new activity on top of the current task.
                    addingToTask = true;
                    sourceRecord = intentActivity;
                } else if (!intentActivity.task.rootWasReset) {
                    // In this case we are launching in to an existing task
                    // that has not yet been started from its front door.
                    // The current task has been brought to the front.
                    // Ideally, we'd probably like to place this new task
                    // at the bottom of its stack, but that's a little hard
                    // to do with the current organization of the code so
                    // for now we'll just drop it.
                    intentActivity.task.setIntent(r);
                }
                if (!addingToTask && reuseTask == null) {
                    // 如果不需要加入指定的task,且不用複用task,那麼直接把找到的目標activity推到前臺
                    // 並結束啓動流程
                    if (doResume) {
                        targetStack.resumeTopActivityLocked(null, options);
                        if (!movedToFront) {
                            notifyActivityDrawnForKeyguard();
                        }
                    } else {
                        ActivityOptions.abort(options);
                    }
                    return ActivityManager.START_TASK_TO_FRONT;
                }
            }//end of (intentActivity != null)
        }//end of (inTask == null && r.resultTo == null)
    }
    if (r.packageName != null) {
        // 待啓動activity包名不爲空
        ActivityStack topStack = mFocusedStack;
        ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
        if (top != null && r.resultTo == null) {
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                // 待啓動的activity和前臺顯示的activity是同一個activity的情況
                if (top.app != null && top.app.thread != null) {
                    if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                        || launchSingleTop || launchSingleTask) {
                        ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
                                top.task);
                        topStack.mLastPausedActivity = null;
                        if (doResume) {
                            resumeTopActivitiesLocked();
                        }
                        ActivityOptions.abort(options);
                        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                            return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                        }
                        top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                        return ActivityManager.START_DELIVERED_TO_TOP;
                    }
                }
            }
        }
    } else {
        //如果目標activity包名爲空,表示找不到待啓動的activity,結束啓動流程
        if (r.resultTo != null && r.resultTo.task.stack != null) {
            r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
                    r.requestCode, Activity.RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return ActivityManager.START_CLASS_NOT_FOUND;
    }

 目標activity不存在的情況:

 // 接下來處理目標activity不存在的情況
    boolean newTask = false;
    boolean keepCurTransition = false;
    TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
            sourceRecord.task : null;
    if (r.resultTo == null && inTask == null && !addingToTask
            && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        // 這種情況下要在一個新的task中啓動activity
        newTask = true;
        targetStack = computeStackFocus(r, newTask);
        targetStack.moveToFront("startingNewTask");
        if (reuseTask == null) {
            // 如果沒有可以複用的就新建一個
            r.setTask(targetStack.createTaskRecord(getNextTaskId(),
                    newTaskInfo != null ? newTaskInfo : r.info,
                    newTaskIntent != null ? newTaskIntent : intent,
                    voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
                    taskToAffiliate);
        } else {
            // 複用task
            r.setTask(reuseTask, taskToAffiliate);
        }
        if (isLockTaskModeViolation(r.task)) {
            return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
        if (!movedHome) {
            if ((launchFlags &
                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
                // 把當前新啓動的任務置於Home任務之上,也就是按back鍵從這個任務返回的時候
                // 會回到home,即使這個不是他們最後看見的activity
                r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
            }
        }
    } else if (sourceRecord != null) {
        // 不用在新task中啓動activity
        final TaskRecord sourceTask = sourceRecord.task;
        if (isLockTaskModeViolation(sourceTask)) {
            return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
        // 那麼目標activity的棧也就是調用者所在的棧
        targetStack = sourceTask.stack;
        targetStack.moveToFront("sourceStackToFront");
        final TaskRecord topTask = targetStack.topTask();
        if (topTask != sourceTask) {
            // 移動task到前臺
            targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
                    r.appTimeTracker, "sourceTaskToFront");
        }
        if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
            // 清除activity
            ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
            keepCurTransition = true;
            if (top != null) {
                ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                targetStack.mLastPausedActivity = null;
                if (doResume) {
                    targetStack.resumeTopActivityLocked(null);
                }
                ActivityOptions.abort(options);
                return ActivityManager.START_DELIVERED_TO_TOP;
            }
        } else if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
            final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
            if (top != null) {
                final TaskRecord task = top.task;
                task.moveActivityToFrontLocked(top);
                ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
                top.updateOptionsLocked(options);
                top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                targetStack.mLastPausedActivity = null;
                if (doResume) {
                    targetStack.resumeTopActivityLocked(null);
                }
                return ActivityManager.START_DELIVERED_TO_TOP;
            }
        }
        r.setTask(sourceTask, null);
    } else if (inTask != null) {
        // 在指定的task中啓動activity
        if (isLockTaskModeViolation(inTask)) {
            return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
        targetStack = inTask.stack;
        targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker,
                "inTaskToFront");
        // check一下是在這個task中啓動一個新的activity或者是複用當前棧頂的activity
        ActivityRecord top = inTask.getTopActivity();
        if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
            if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                    || launchSingleTop || launchSingleTask) {
                ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
                if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                    return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                }
                top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                return ActivityManager.START_DELIVERED_TO_TOP;
            }
        }
        if (!addingToTask) {
            ActivityOptions.abort(options);
            return ActivityManager.START_TASK_TO_FRONT;
        }
        r.setTask(inTask, null);
    } else {
        // 既不啓動一個新的activity,也不在指定的task中啓動
        // 目前不會走到這個分支中
        targetStack = computeStackFocus(r, newTask);
        targetStack.moveToFront("addingToTopTask");
        ActivityRecord prev = targetStack.topActivity();
        r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
                        r.info, intent, null, null, true), null);
        mWindowManager.moveTaskToTop(r.task.taskId);
    }
    mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
            intent, r.getUriPermissionsLocked(), r.userId);
    if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
        r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
    }
    if (newTask) {
        EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
    }
    ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
    targetStack.mLastPausedActivity = null;
    // 進行下一步流程,啓動activity
    targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
    if (!launchTaskBehind) {
        // 如果不是在後臺啓動就把焦點設置在當前activity
        mService.setFocusedActivityLocked(r, "startedActivity");
    }
    return ActivityManager.START_SUCCESS;
}

可以看到這個方法首先是修正了一些啓動參數,接着根據目標Activity是否存在分別進行了處理,然後啓動activity。 

  • ActivityStack.startActivityLocked :判斷是否需要創建一個新的任務來啓動Activity。
final void startActivityLocked(ActivityRecord r, boolean newTask,
        boolean doResume, boolean keepCurTransition, Bundle options) {
    TaskRecord rTask = r.task;
    final int taskId = rTask.taskId;
    if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
        // 歷史activity被清除了或者是明確要求在新的task啓動activity
        // 將task插入stack棧頂
        insertTaskAtTop(rTask, r);
        // 調用WindowManagerService 
        mWindowManager.moveTaskToTop(taskId);
    }
    TaskRecord task = null;
    if (!newTask) {
        // 在一個已經存在的task中啓動activity
        boolean startIt = true;// 是否需要啓動activity的標誌位
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            task = mTaskHistory.get(taskNdx);
            if (task.getTopActivity() == null) {
                //  該task中已經沒有activity了
                continue;
            }
            if (task == r.task) {
                // 匹配到目標task
                if (!startIt) {
                    // 如果不需要啓動,就先添加到棧頂
                    task.addActivityToTop(r);
                    r.putInHistory();
                    // 調用WindowManagerService 添加apptoken
                    mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                            r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                            (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
                            r.userId, r.info.configChanges, task.voiceSession != null,
                            r.mLaunchTaskBehind);
                    if (VALIDATE_TOKENS) {
                        validateAppTokensLocked();
                    }
                    ActivityOptions.abort(options);
                    return;
                }
                break;
            } else if (task.numFullscreen > 0) {
                // 如果在這個任務中有全屏顯示的activity,就先不顯示
                startIt = false;
            }
        }
    }
    // 走到這裏已經把目標activity所在的task推到了stack的棧頂
    // 如果不需要在新的activity中啓動,而且上面查到了目標task,且task在棧頂,就不需要調用onUserLeaving方法
    if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
        mStackSupervisor.mUserLeaving = false;
    }
    task = r.task;
    // 將activity放到task的棧頂
    task.addActivityToTop(r);
    // activity移動或者銷燬之後調用setFrontOfTask方法
    task.setFrontOfTask();
    r.putInHistory();
    if (!isHomeStack() || numActivities() > 0) {
        // 進入這個分支的條件當前stack不是桌面stack,也即當前是否是桌面。或者當前stack中已有task
        // 一些切換動畫相關的操作
        boolean showStartingIcon = newTask;
        ProcessRecord proc = r.app;
        if (proc == null) {
            proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
        }
        if (proc == null || proc.thread == null) {
            showStartingIcon = true;
        }
        if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
            mNoAnimActivities.add(r);
        } else {
            mWindowManager.prepareAppTransition(newTask
                    ? r.mLaunchTaskBehind
                            ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
                            : AppTransition.TRANSIT_TASK_OPEN
                    : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
            mNoAnimActivities.remove(r);
        }
        // 調用WindowManagerService 添加apptoken
        mWindowManager.addAppToken(task.mActivities.indexOf(r),
                r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
        boolean doShow = true;
        // 一些顯示StartingWindow的操作
        if (newTask) {
            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                resetTaskIfNeededLocked(r, r);
                doShow = topRunningNonDelayedActivityLocked(null) == r;
            }
        } else if (options != null && new ActivityOptions(options).getAnimationType()
                == ActivityOptions.ANIM_SCENE_TRANSITION) {
            doShow = false;
        }
        if (r.mLaunchTaskBehind) {
            mWindowManager.setAppVisibility(r.appToken, true);
            ensureActivitiesVisibleLocked(null, 0);
        } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
            ActivityRecord prev = mResumedActivity;
            // prev 表示當前在resumed狀態的activity
            if (prev != null) {
                // 如果它和目標activity不在同一個task
                if (prev.task != r.task) {
                    prev = null;
                }
                // 在同一個task且已經顯示
                else if (prev.nowVisible) {
                    prev = null;
                }
            }
            mWindowManager.setAppStartingWindow(
                    r.appToken, r.packageName, r.theme,
                    mService.compatibilityInfoForPackageLocked(
                            r.info.applicationInfo), r.nonLocalizedLabel,
                    r.labelRes, r.icon, r.logo, r.windowFlags,
                    prev != null ? prev.appToken : null, showStartingIcon);
            r.mStartingWindowShown = true;
        }
    } else {
        // 進入這個分支條件:目標stack中還沒有任何activity,那就不要做任何動畫
        // 調用addAppToken綁定窗口
        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
        ActivityOptions.abort(options);
        options = null;
    }
    if (VALIDATE_TOKENS) {
        validateAppTokensLocked();
    }
    // 顯示activity
    if (doResume) {
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }
}
  • ActivityStack.resumeTopActivityLocked :獲取棧頂的activity,並通知Launcher應該pause掉這個Activity以便啓動新的activity。
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }
    boolean result = false;
    try {
        // 防止遞歸調用
        mStackSupervisor.inResumeTopActivity = true;
        if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
            mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
            mService.updateSleepIfNeededLocked();
        }
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;
}
  • ActivityStack.startPausingLocked
    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {
        if (mPausingActivity != null) {
            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                    + " state=" + mPausingActivity.getState());
            if (!shouldSleepActivities()) {
                // Avoid recursion among check for sleep and complete pause during sleeping.
                // Because activity will be paused immediately after resume, just let pause
                // be completed by the order of activity paused from clients.
                completePauseLocked(false, resuming);
            }
        }
        ActivityRecord prev = mResumedActivity;

        if (prev == null) {
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }

        if (prev == resuming) {
            Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
            return false;
        }

        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
        else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
        prev.setState(PAUSING, "startPausingLocked");
        prev.getTask().touchActiveTime();
        clearLaunchTime(prev);

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

        mService.updateCpuStats();

        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
            try {
                EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName, "userLeaving=" + userLeaving);
                mService.updateUsageStats(prev, false);

                mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                        PauseActivityItem.obtain(prev.finishing, userLeaving,
                                prev.configChangeFlags, pauseImmediately));
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }

        // If we are not going to sleep, we want to ensure the device is
        // awake until the next activity is started.
        if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
            mStackSupervisor.acquireLaunchWakelock();
        }

        if (mPausingActivity != null) {
            // Have the window manager pause its key dispatching until the new
            // activity has started.  If we're pausing the activity just because
            // the screen is being turned off and the UI is sleeping, don't interrupt
            // key dispatch; the same activity will pick it up again on wakeup.
            if (!uiSleeping) {
                prev.pauseKeyDispatchingLocked();
            } else if (DEBUG_PAUSE) {
                 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
            }

            if (pauseImmediately) {
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                completePauseLocked(false, resuming);
                return false;

            } else {
                schedulePauseTimeout(prev);
                return true;
            }

        } else {
            // This activity failed to schedule the
            // pause, so just treat it as being paused now.
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
            if (resuming == null) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }
    }
  • ApplicationThreadProxy.schedulePauseActivity

第三階段: pause Launcher的Activity,並通知AMS已經paused(在Launcher所在進程執行)

  • ApplicationThread.schedulePauseActivity
       public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            int seq = getLifecycleSeq();
            if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
                    + " operation received seq: " + seq);
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                    configChanges,
                    seq);
        }
  • ActivityThread.queueOrSendMessage
  • H.handleMessage
 public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case EXIT_APPLICATION:
                    if (mInitialApplication != null) {
                        mInitialApplication.onTerminate();
                    }
                    Looper.myLooper().quit();
                    break;
                case RECEIVER:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
                    handleReceiver((ReceiverData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case BIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                    handleBindService((BindServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case UNBIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
                    handleUnbindService((BindServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case SERVICE_ARGS:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
                    handleServiceArgs((ServiceArgsData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case STOP_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
                    handleStopService((IBinder)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case CONFIGURATION_CHANGED:
                    handleConfigurationChanged((Configuration) msg.obj);
                    break;
                case CLEAN_UP_CONTEXT:
                    ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
                    cci.context.performFinalCleanup(cci.who, cci.what);
                    break;
                case GC_WHEN_IDLE:
                    scheduleGcIdler();
                    break;
                case DUMP_SERVICE:
                    handleDumpService((DumpComponentInfo)msg.obj);
                    break;
                case LOW_MEMORY:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
                    handleLowMemory();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case PROFILER_CONTROL:
                    handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
                    break;
                case CREATE_BACKUP_AGENT:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
                    handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case DESTROY_BACKUP_AGENT:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
                    handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case SUICIDE:
                    Process.killProcess(Process.myPid());
                    break;
                case REMOVE_PROVIDER:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
                    completeRemoveProvider((ProviderRefCount)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case ENABLE_JIT:
                    ensureJitEnabled();
                    break;
                case DISPATCH_PACKAGE_BROADCAST:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
                    handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case SCHEDULE_CRASH:
                    throw new RemoteServiceException((String)msg.obj);
                case DUMP_HEAP:
                    handleDumpHeap((DumpHeapData) msg.obj);
                    break;
                case DUMP_ACTIVITY:
                    handleDumpActivity((DumpComponentInfo)msg.obj);
                    break;
                case DUMP_PROVIDER:
                    handleDumpProvider((DumpComponentInfo)msg.obj);
                    break;
                case SLEEPING:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
                    handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case SET_CORE_SETTINGS:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
                    handleSetCoreSettings((Bundle) msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case UPDATE_PACKAGE_COMPATIBILITY_INFO:
                    handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
                    break;
                case UNSTABLE_PROVIDER_DIED:
                    handleUnstableProviderDied((IBinder)msg.obj, false);
                    break;
                case REQUEST_ASSIST_CONTEXT_EXTRAS:
                    handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
                    break;
                case TRANSLUCENT_CONVERSION_COMPLETE:
                    handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
                    break;
                case INSTALL_PROVIDER:
                    handleInstallProvider((ProviderInfo) msg.obj);
                    break;
                case ON_NEW_ACTIVITY_OPTIONS:
                    Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
                    onNewActivityOptions(pair.first, pair.second);
                    break;
                case ENTER_ANIMATION_COMPLETE:
                    handleEnterAnimationComplete((IBinder) msg.obj);
                    break;
                case START_BINDER_TRACKING:
                    handleStartBinderTracking();
                    break;
                case STOP_BINDER_TRACKING_AND_DUMP:
                    handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
                    break;
                case LOCAL_VOICE_INTERACTION_STARTED:
                    handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
                            (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
                    break;
                case ATTACH_AGENT: {
                    Application app = getApplication();
                    handleAttachAgent((String) msg.obj, app != null ? app.mLoadedApk : null);
                    break;
                }
                case APPLICATION_INFO_CHANGED:
                    mUpdatingSystemConfig = true;
                    try {
                        handleApplicationInfoChanged((ApplicationInfo) msg.obj);
                    } finally {
                        mUpdatingSystemConfig = false;
                    }
                    break;
                case RUN_ISOLATED_ENTRY_POINT:
                    handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1,
                            (String[]) ((SomeArgs) msg.obj).arg2);
                    break;
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;
                case RELAUNCH_ACTIVITY:
                    handleRelaunchActivityLocally((IBinder) msg.obj);
                    break;
            }
            Object obj = msg.obj;
            if (obj instanceof SomeArgs) {
                ((SomeArgs) obj).recycle();
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
        }
  • ActivityThread.handlePauseActivity
    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            if (userLeaving) {
                performUserLeavingActivity(r);
            }

            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(r, finished, reason, pendingActions);

            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }
            mSomeActivitiesChanged = true;
        }
    }
  • ActivityManagerProxy.activityPaused

第四階段:檢查activity所在進程是否存在,如果存在,就直接通知這個進程,在該進程中啓動Activity;不存在的話,會調用Process.start創建一個新進程(執行在AMS進程)

  • ActivityManagerService.activityPaused
    @Override
    public final void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }
  • ActivityStack.activityPaused
  • ActivityStack.completePauseLocked
 private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);

        if (prev != null) {
            final boolean wasStopping = prev.state == STOPPING;
            prev.state = ActivityState.PAUSED;
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
            } else if (prev.app != null) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
                        + " wasStopping=" + wasStopping + " visible=" + prev.visible);
                if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                            "Complete pause, no longer waiting: " + prev);
                }
                if (prev.deferRelaunchUntilPaused) {
                    // Complete the deferred relaunch that was waiting for pause to complete.
                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
                    prev.relaunchActivityLocked(false /* andResume */,
                            prev.preserveWindowOnDeferredRelaunch);
                } else if (wasStopping) {
                    // We are also stopping, the stop request must have gone soon after the pause.
                    // We can't clobber it, because the stop confirmation will not be handled.
                    // We don't need to schedule another stop, we only need to let it happen.
                    prev.state = STOPPING;
                } else if ((!prev.visible && !hasVisibleBehindActivity())
                        || mService.isSleepingOrShuttingDownLocked()) {
                    // Clear out any deferred client hide we might currently have.
                    prev.setDeferHidingClient(false);
                    // If we were visible then resumeTopActivities will release resources before
                    // stopping.
                    addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
                }
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
                prev = null;
            }
            // It is possible the activity was freezing the screen before it was paused.
            // In that case go ahead and remove the freeze this activity has on the screen
            // since it is no longer visible.
            if (prev != null) {
                prev.stopFreezingScreenLocked(true /*force*/);
            }
            mPausingActivity = null;
        }

        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDownLocked()) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
            } else {
                mStackSupervisor.checkReadyForSleepLocked();
                ActivityRecord top = topStack.topRunningActivityLocked();
                if (top == null || (prev != null && top != prev)) {
                    // If there are no more activities available to run, do resume anyway to start
                    // something. Also if the top activity on the stack is not the just paused
                    // activity, we need to go ahead and resume it to ensure we complete an
                    // in-flight app switch.
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                }
            }
        }

        if (prev != null) {
            prev.resumeKeyDispatchingLocked();

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

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

        mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
    }
  • ActivityStack.resumeTopActivityLocked
  • ActivityStack.startSpecificActivityLocked
  • ActivityManagerService.startProcessLocked
    @GuardedBy("this")
    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 */);
    }
    @GuardedBy("this")
    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) {
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            checkTime(startTime, "startProcess: after getProcessRecord");

            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
                // If we are in the background, then check to see if this process
                // is bad.  If so, we will just silently fail.
                if (mAppErrors.isBadProcessLocked(info)) {
                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
                            + "/" + info.processName);
                    return null;
                }
            } else {
                // When the user is explicitly starting a process, then clear its
                // crash count so that we won't make it bad until they see at
                // least one crash dialog again, and make the process good again
                // if it had been bad.
                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
                        + "/" + info.processName);
                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 {
            // If this is an isolated process, it can't re-use an existing process.
            app = null;
        }

        // We don't have to do anything more if:
        // (1) There is an existing application record; and
        // (2) The caller doesn't think it is dead, OR there is no thread
        //     object attached to it so we know it couldn't have crashed; and
        // (3) There is a pid assigned to it, so it is either starting or
        //     already running.
        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
                + " app=" + app + " knownToBeDead=" + knownToBeDead
                + " thread=" + (app != null ? app.thread : null)
                + " pid=" + (app != null ? app.pid : -1));
        if (app != null && app.pid > 0) {
            if ((!knownToBeDead && !app.killed) || app.thread == null) {
                // We already have the app running, or are waiting for it to
                // come up (we have a pid but not yet its thread), so keep it.
                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
                // If this is a new package in the process, add the package to the list
                app.addPackage(info.packageName, info.versionCode, mProcessStats);
                checkTime(startTime, "startProcess: done, added package to proc");
                return app;
            }

            // An application record is attached to a previous process,
            // clean it up now.
            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
            checkTime(startTime, "startProcess: bad proc running, killing");
            killProcessGroup(app.uid, app.pid);
            handleAppDiedLocked(app, true, true);
            checkTime(startTime, "startProcess: done killing old proc");
        }

        String hostingNameStr = hostingName != null
                ? hostingName.flattenToShortString() : null;

        if (app == null) {
            checkTime(startTime, "startProcess: creating new process record");
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
            if (app == null) {
                Slog.w(TAG, "Failed making new process record for "
                        + processName + "/" + info.uid + " isolated=" + isolated);
                return null;
            }
            app.crashHandler = crashHandler;
            app.isolatedEntryPoint = entryPoint;
            app.isolatedEntryPointArgs = entryPointArgs;
            checkTime(startTime, "startProcess: done creating new process record");
        } else {
            // If this is a new package in the process, add the package to the list
            app.addPackage(info.packageName, info.versionCode, mProcessStats);
            checkTime(startTime, "startProcess: added package to existing proc");
        }

        // If the system is not ready yet, then hold off on starting this
        // process until it is.
        if (!mProcessesReady
                && !isAllowedWhileBooting(info)
                && !allowWhileBooting) {
            if (!mProcessesOnHold.contains(app)) {
                mProcessesOnHold.add(app);
            }
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
                    "System not ready, putting on hold: " + app);
            checkTime(startTime, "startProcess: returning with proc on hold");
            return app;
        }

        checkTime(startTime, "startProcess: stepping in to startProcess");
        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
        checkTime(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }
  • Process.start //在這裏創建了新進程,新的進程會導入ActivityThread類,並執行它的main函數

第五階段: 創建ActivityThread實例,執行一些初始化操作,並綁定Application。如果Application不存在,會調用LoadedApk.makeApplication創建一個新的Application對象。之後進入Loop循環。(執行在新創建的app進程)

  • ActivityThread.main
  • ActivityThread.attach(false) //聲明不是系統進程
  • ActivityManagerProxy.attachApplication

第六階段:處理新的應用進程發出的創建進程完成的通信請求,並通知新應用程序進程啓動目標Activity組件(執行在AMS進程)

  • ActivityManagerService.attachApplication //AMS綁定本地ApplicationThread對象,後續通過ApplicationThreadProxy來通信。
  • ActivityManagerService.attachApplicationLocked
  • ActivityStack.realStartActivityLocked //真正要啓動Activity了!
  • ApplicationThreadProxy.scheduleLaunchActivity //AMS通過ATP通知app進程啓動Activity

第七階段: 加載MainActivity類,調用onCreate聲明週期方法(執行在新啓動的app進程)

  • ApplicationThread.scheduleLaunchActivity //ApplicationThread發消息給AT
  • ActivityThread.queueOrSendMessage
  • H.handleMessage //AT的Handler來處理接收到的LAUNCH_ACTIVITY的消息
  • ActivityThread.handleLaunchActivity
  • ActivityThread.performLaunchActivity
  • Instrumentation.newActivity //調用Instrumentation類來新建一個Activity對象
  • Instrumentation.callActivityOnCreate
  • MainActivity.onCreate
  • ActivityThread.handleResumeActivity
  • AMP.activityResumed
  • AMS.activityResumed(AMS進程)

 

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