Android6.0 Activity啟動(dòng)流程解析

API版本 23
本例從Launcher 啟動(dòng)一個(gè) 應(yīng)用開(kāi)始分析

# Activity.startActivityForResult

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                                   @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        // 調(diào)用 Instrumentation.execStartActivity()
        Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
        //...
    } else {
        //...
    }
}
  • mMaintThread -> 類(lèi)型為 ActivityThread, 每個(gè)進(jìn)程都有一份
  • mToken -> 類(lèi)型為 IBinder, 指向 ActivityRecordBinder 本地對(duì)象. 每一個(gè)已經(jīng)啟動(dòng)的 Activity 組件在 ActivityManagerService(以下簡(jiǎn)稱(chēng)ASM) 中都有一個(gè)對(duì)應(yīng)的 ActivityRecord 對(duì)象, 用來(lái)維護(hù)對(duì)應(yīng)的 Activity 組件的運(yùn)行狀態(tài)及信息.
  • ActivityRecord 為重要變量, 可以把他認(rèn)為是 Activity 即可.

略過(guò)中間部分, 直接來(lái)到 ActivityStackSupervisor.startActivityMayWait 方法, Binder通信, 不是本文重點(diǎn).
ActivityStackSupervisor 整個(gè)系統(tǒng)中只有一個(gè), 可以認(rèn)為是管理全局 Activity 組件的類(lèi)就可以.

# 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) {
    
    // 是否指明了 Component, 可以省去 Intent匹配搜索
    boolean componentSpecified = intent.getComponent() != null;

    // 查詢(xún)滿足條件的 Activity, 和 PKMS 交互
    ActivityInfo aInfo =
        resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);

    synchronized (mService) {
        // 獲取調(diào)用者的 pid, 和 uid
        final int realCallingPid = Binder.getCallingPid();
        final int realCallingUid = Binder.getCallingUid();
        // ...

        final ActivityStack stack;
        if (container == null || container.mStack.isOnHomeDisplay()) {
            stack = mFocusedStack;
        } else {
            stack = container.mStack;
        }

        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                                      voiceSession, voiceInteractor, resultTo, resultWho,
                                      requestCode, callingPid, callingUid, callingPackage,
                                      realCallingPid, realCallingUid, startFlags, options, 
                                      ignoreTargetSecurity, componentSpecified, null, 
                                      container, inTask);
        
        //...
        return res;
    }
}
  • 根據(jù)安裝后的信息, 查詢(xún) Activity 信息.

# ActivityStackSupervisor. startActivityLocked

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) {
    // caller 調(diào)用者即Launcher ApplicationThreadProxy
    // aInfo 即將啟動(dòng)的Activity信息
    // resultTo 調(diào)用者的 ActivityRecord$Token
    
    int err = ActivityManager.START_SUCCESS;
    
    // 第一步
    ProcessRecord callerApp = null;
        if (caller != null) {
            // 根據(jù)caller 獲取調(diào)用者進(jìn)程信息即Launcher進(jìn)程信息
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                // 得到這個(gè)調(diào)用者的 pid 和 uid.
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
    //...
    
    // 描述調(diào)用者 Activity即Launcher
    ActivityRecord sourceRecord = null;
    // 描述接收調(diào)用結(jié)果的 Activity, 本例不接收結(jié)果
    ActivityRecord resultRecord = null;
    if (resultTo != null) {
        // 根據(jù) resultTo 獲取 Launcher的ActivityRecord
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {
            // requestCode 默認(rèn)傳入 -1, 所以這里 resultRecord 為空
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
    
    final int launchFlags = intent.getFlags();
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        // 如果存在這個(gè)標(biāo)志位FLAG_ACTIVITY_FORWARD_RESULT, 
        // 那么就需要修改 接受調(diào)用結(jié)果的Activity, resultRecord, 與本例無(wú)關(guān)
    }
    
    // 一堆跳轉(zhuǎn)驗(yàn)證, 不能解析Intent, 沒(méi)找到Activity, 等等

    if (err != ActivityManager.START_SUCCESS) {
        // 如果中間出錯(cuò), 并且接收結(jié)果的 resultRecord 不為空, 返回RESULT_CANCELED
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1,
                                                 resultRecord, resultWho, requestCode,
                                                 Activity.RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return err;
    }
    
    //...
    // 創(chuàng)建ActivityRecord, 用來(lái)描述即將啟動(dòng)的 Activity
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                                          intent, resolvedType, aInfo,
                                          mService.mConfiguration, resultRecord,
                                          resultWho, requestCode, componentSpecified,
                                          voiceSession != null, mSupervisor, container, 
                                          options, sourceRecord);
    
    //...
    err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);
    
    //...
    return err;
}
  • 每個(gè)應(yīng)用程序的進(jìn)程都使用一個(gè) ProcessRecord 來(lái)描述, 并且保存在 AMS 內(nèi)部.
  • 權(quán)限驗(yàn)證, 解析 intent 后是否找到了對(duì)應(yīng)的 Activity
  • 創(chuàng)建了即將啟動(dòng)頁(yè)面的 ActivityRecord 對(duì)象

中間略過(guò)了比較多的步驟, 例如啟動(dòng) pendingActivity 集合中的 Activity , 是否允許切換App等等. 我們只走主線, 后面代碼可能連 ... 也不會(huì)標(biāo)出來(lái)了.

# ActivityStackSupervisor.startActivityUnchecked

final int startActivityUncheckedLocked(final ActivityRecord r, 
                                       ActivityRecord sourceRecord,
                                       IVoiceInteractionSession voiceSession, 
                                       IVoiceInteractor voiceInteractor, int startFlags,
                                       boolean doResume, Bundle options, 
                                       TaskRecord inTask) {
    // r 描述即將啟動(dòng)的 ActivityRecord
    // sourceRecord 描述調(diào)用者的 ActivityRecord
    // doResume true
    
    // 處理啟動(dòng)模式
    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;
    // 當(dāng)存在結(jié)果接收者并且, 標(biāo)志 FLAG_ACTIVITY_NEW_TASK時(shí), 返回 RESULT_CANCELED
    if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0
        && r.resultTo.task.stack != null) {
        r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 
                                                       r.requestCode, 
                                                       Activity.RESULT_CANCELED, null);
        r.resultTo = null;
    }   
    
    boolean addingToTask = false;
    TaskRecord reuseTask = null;
    // 根據(jù)啟動(dòng)模式標(biāo)志 FLAG_ACTIVITY_NEW_TASK
    if (inTask == null) {
        if (sourceRecord == null) {
            //...
        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        } else if (launchSingleInstance || launchSingleTask) {
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        }
    }
    ActivityInfo newTaskInfo = null;
    Intent newTaskIntent = null;
    ActivityStack sourceStack;
    boolean movedHome = false;
    ActivityStack targetStack;
    intent.setFlags(launchFlags);
    
    if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
         (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
        || launchSingleInstance || launchSingleTask) {
        // ...
        // 根據(jù)flag判斷啟動(dòng)模式, 另開(kāi)文章討論
    }
    
    // 上面一堆 flag 判斷, 是為了決定 Activity 該存放在哪個(gè)棧里
    if (r.packageName != null) {
        // 原焦點(diǎn)Stack, 本例為表示桌面的 ActivityStack
        ActivityStack topStack = mFocusedStack;
        // 正在頂部運(yùn)行的 Activity 即 Launcher
        ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
        // 如果正在啟動(dòng)的活動(dòng)與當(dāng)前位于頂部的活動(dòng)相同,考慮 singleTop
        if (top != null && r.resultTo == null) {
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                // ...
                // 處理singleTop
            }
        }
    }

    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) {
        newTask = true;
        // 獲取ActivityStack, 如果沒(méi)有就創(chuàng)建
        targetStack = computeStackFocus(r, newTask);
        // 將targetStack 移至頂部, 
        // mFocusedStack賦值為targetStack, 變更了焦點(diǎn)Stack
        // mLastFocusedStack賦值為原 ActivityStack
        targetStack.moveToFront("startingNewTask");

        // 給即將啟動(dòng)的ActivityRecord, 設(shè)置TaskRecord
        if (reuseTask == null) {
            // createTaskRecord() 會(huì)創(chuàng)建TaskRecord
            // 并添加到 targetStack 中的 mTaskHistory中
            r.setTask(targetStack.createTaskRecord(getNextTaskId(),
                                                   newTaskInfo != null ? newTaskInfo 
                                                   r.info, newTaskIntent != null ? 
                                                   newTaskIntent : intent,
                                                   voiceSession, voiceInteractor, 
                                                   !launchTaskBehind /* toTop */), 
                      taskToAffiliate);
        } else {
            r.setTask(reuseTask, taskToAffiliate);
        }

    }
    
    // mLastPausedActivity 置空
    targetStack.mLastPausedActivity = null;
    targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
}
  • TaskRecord 表示棧, 它里面保存了在該棧中保存的 Activity 集合.
  • ActivityStack 用于管理 TaskRecord , 一般情況下只有表示桌面的 ActivityStack , 和應(yīng)用程序的 ActivityStack, 多屏幕狀態(tài)下可能會(huì)不一樣, 沒(méi)有驗(yàn)證.

桌面的 ActivityStack 存有兩個(gè) TaskRecord , 分別存著 LauncherRecentActivity

ActivityStack , TaskRecord , ActivityRecord 三者的關(guān)系如圖:

ActivityStack, TaskRecord, ActivityRecord關(guān)系圖.png

  • 上面的代碼用一句話概括就是, 根據(jù)配置判斷是否要新建棧 .

# ActivityStack.startActivityLocked

final void startActivityLocked(ActivityRecord r, boolean newTask, 
                               boolean keepCurTransition, ActivityOptions options) {
    TaskRecord rTask = r.task;
    final int taskId = rTask.taskId;
    TaskRecord task = null;
    
    if (!newTask) {
        // 如果不是新建Task棧, 則找到合適的棧
    }
    task = r.task;
    
    // 將要啟動(dòng)的ActivityRecord 添加到TastRecord.mActivityes 集合的最尾部
    task.addActivityToTop(r);    
    // 添加了新的Activity, 所以需要給 ActivityRecord的變量frontOfTask重新賦值
    // 該變量在后面會(huì)用到, 表示是否是 TaskRecord集合中第一個(gè)元素, 也就是根元素
    task.task.setFrontOfTask();
    //...
    
    // 上面?zhèn)鬟^(guò)來(lái) true
    if (doResume) {
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }
}
  • 找到合適的棧, 并且置頂

跳過(guò)兩個(gè)簡(jiǎn)單方法, 直接定位到下面方法

# ActivityStack.resumeTopActivityLocked

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    // prev, 即將啟動(dòng)的ActivityRecord
    // (只限于該步驟, 多處調(diào)用該方法, 那時(shí)的prev意義不一樣)

    // 獲取該ActivityStack, TaskRecord集合中最后一個(gè)元素
    // TaskRecord中 Activity集合中最后一個(gè)非finishing的 ActivityRecord
    // 因?yàn)樵谏厦娣治鲋? TaskRecord已經(jīng)添加到 mTaskHistory的尾部, 并且
    // ActivityRecord 也添加到對(duì)應(yīng)的 TaskRecord當(dāng)中, 所以這里 next 等同于prev
    final ActivityRecord next = topRunningActivityLocked(null);
    
    final TaskRecord prevTask = prev != null ? prev.task : null;
    next.delayedResume = false;
    if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
        mStackSupervisor.allResumedActivitiesComplete()) {
        // 如果頂部Activity狀態(tài)為RESUMED, 返回
        return false;
    }

    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mWaitingVisibleActivities.remove(next);
    
    //...
    
    // 是否等待 pause
    // FLAG_RESUME_WHILE_PAUSING, 這個(gè)標(biāo)志位可以不等待 PAUSE, 進(jìn)行 RESUME
    // 我們討論一般情況, 該變量為 false
    boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;

    // 從名字中可以看出, 對(duì)backStack執(zhí)行Pause
    // backStack指的是非FocusStack, 因?yàn)樯厦嬉呀?jīng)將焦點(diǎn)Stack變更了
    // 這里backstack指的是桌面的ActivitStack
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
    
    // mResumedActivity是當(dāng)前ActivityStack的成員變量
    // 在本次例中, 新建了ActivityStack, 所以mResumedActivity為空
    if (mResumedActivity != null) {
        pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
    }

    // 上面對(duì)兩個(gè)ActivityStack只要有一個(gè)成功執(zhí)行了pause, 那么這里直接返回
    // 并且整個(gè)系統(tǒng)進(jìn)程調(diào)用完畢, Launcher進(jìn)程被掛起的線程恢復(fù)
    if (pausing) {
        // ...
        return true;
    }

    //************重要的分割線************
    // 其實(shí)下面有很重要的方法, 但是因?yàn)樯厦嬉呀?jīng)返回了.
    // 所以下面暫時(shí)就不用管, 待會(huì)會(huì)執(zhí)行到下面的代碼
    
    // ...
}
  • 找到 Resume 狀態(tài)的 ActivityLauncher .
  • 找到后調(diào)用 ActivityStack.startPausingLocked

看一下兩個(gè)決定 pausing 變量的兩個(gè)函數(shù)

# ActivityStackSupervisor.startPausingLocked

boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
    boolean someActivityPaused = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            // isFrontStack() 判斷是否是焦點(diǎn)Stack
            if (!isFrontStack(stack) && stack.mResumedActivity != null) {
                // 本例中Launcher點(diǎn)擊圖標(biāo), 進(jìn)入應(yīng)用
                // Launcher處在的ActivityStack為backStack
                // mResumedActivity 為 Launcher
                // 調(diào)用 startPausingLocked
                someActivityPaused |= stack.startPausingLocked(userLeaving, false, 
                                                               resuming, dontWait);
            }
        }
    }
    return someActivityPaused;
}

# ActivityStack.startPausingLocked

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, 
                                 boolean resuming, boolean dontWait) {
    //...
    // 表示 Launcher
    ActivityRecord prev = mResumedActivity;
    // 將mResumedActivity置空
    mResumedActivity = null;
    mPausingActivity = prev;
    mLastPausedActivity = prev;
    // 狀態(tài)變更為 PAUSING
    prev.state = ActivityState.PAUSING;
    // 返回即將啟動(dòng)的ActivityRecord
    final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
    if (prev.app != null && prev.app.thread != null) {
        // 查詢(xún) LauncherActivity是否存在
        // 走到應(yīng)用進(jìn)程調(diào)用Pause方法
        // 在 handlePauseActivity() 中, 在返回到系統(tǒng)進(jìn)程
        // 調(diào)用 activityPaused() **重點(diǎn)**
        prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                                              userLeaving, prev.configChangeFlags, 
                                              dontWait);
    } else {
        mPausingActivity = null;
        mLastPausedActivity = null;
        mLastNoHistoryActivity = null;
    }
    if (mPausingActivity != null) {
        if (dontWait) {
            // 特殊標(biāo)志位, 不等待Pause執(zhí)行Resume, 不討論
            completePauseLocked(false);
            return false;
        } else {
            // 走到這個(gè)分支
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
            msg.obj = prev;
            prev.pauseTime = SystemClock.uptimeMillis();
            // 在ServiceThread中執(zhí)行 activityPausedLocked **重點(diǎn)**
            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); // 500ms
            return true;
        }
    } else {
        return false;
    }
}
  • mResumedActivity 置空, 所以現(xiàn)在系統(tǒng)中是沒(méi)有正在 RESUMEActivity , 所以如果下次進(jìn)入 resumeTopActivityInnerLocked , 因?yàn)闆](méi)有要 PAUSEActivity , 所以不會(huì)返回 .

  • 以下兩個(gè)方法最終會(huì)掉用同一個(gè)方法.

    • ActivityThread.schedulePauseActivity
    • 系統(tǒng)進(jìn)程中給 ServiceThread 發(fā)送了 PAUSE_TIMEOUT_MSG 消息

# ActivityThread. handlePauseActivity

private void handlePauseActivity(IBinder token, boolean finished,
                                 boolean userLeaving, int configChanges, boolean dontReport) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        // 調(diào)用 Activity 的 onPause() 方法
        performPauseActivity(token, finished, r.isPreHoneycomb());

        // Tell the activity manager we have paused.
        if (!dontReport) {
            try {
                // 調(diào)用 AMS 的 activityPaused()
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
            }
        }
        mSomeActivitiesChanged = true;
    }
}
  • 執(zhí)行了 LauncheronPause 后, 緊接著回調(diào)給 AMS , AMS.activityPaused() -> ActivityStack.activityPausedLocked(),

接下來(lái)在看在系統(tǒng)進(jìn)程發(fā)送的 PAUSE_TIMEOUT_MSG 消息.

# ActivityStackHandler.handleMessage

public void handleMessage(Message msg) {
    //...
    case PAUSE_TIMEOUT_MSG: {
        ActivityRecord r = (ActivityRecord)msg.obj;
        synchronized (mService) {
            // 同樣調(diào)用了, activityPausedLocked, 但是在發(fā)送該消息時(shí)是延遲了500秒
            activityPausedLocked(r.appToken, true);
        }
    } break;
}
  • 系統(tǒng)中很多類(lèi)似這種超時(shí)消息, 確保在進(jìn)程通信卡住時(shí), 該方法也能夠正確調(diào)用

# ActivityStack.activityPausedLocked

final void activityPausedLocked(IBinder token, boolean timeout) {
    // 本例中Launcher
    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        // 移除Handler消息, 有可能是Handler進(jìn)到這, 
        // 有可能是應(yīng)用進(jìn)程通過(guò)系統(tǒng)進(jìn)程進(jìn)入這里, 不同的是參數(shù)timeout
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {
            // 進(jìn)入該分支
            completePauseLocked(true);
        } else {
            if (r.finishing && r.state == ActivityState.PAUSING) {
                finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
            }
        }
    }
}
  • 這個(gè)函數(shù)沒(méi)什么好講的, 移除了PAUSE_TIMEOUT_MSG消息

# ActivityStack.completePauseLocked

private void completePauseLocked(boolean resumeNext) {
    ActivityRecord prev = mPausingActivity;
    if (prev != null) {
        prev.state = ActivityState.PAUSED;
        if (prev.finishing) {
            // 立即結(jié)束
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
        } else if (prev.app != null) {
            if (prev.configDestroy) {
            // ...
            } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) 
            {
                // 添加到StoppingActivity集合中, 過(guò)會(huì)會(huì)執(zhí)行onStop
                mStackSupervisor.mStoppingActivities.add(prev);
                // 如果StoppingActivity集合中已經(jīng)堆積了3個(gè)以上要停止的活動(dòng)
                // 或者該Activity是TaskRecord棧中最后一個(gè), 
                // 發(fā)送IDLE_NOW_MSG消息, 該方法中會(huì)執(zhí)行 onStop, onDestroy等
                // 文字最后解析
                if (mStackSupervisor.mStoppingActivities.size() > 3 ||
                    prev.frontOfTask && mTaskHistory.size() <= 1) {
                    mStackSupervisor.scheduleIdleLocked();
                } else {
                    mStackSupervisor.checkReadyForSleepLocked();
                }
            }
        } else {
            prev = null;
        }
    }
    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        // 繼續(xù)調(diào)用 resumeTopActivitiesLocked
        if (!mService.isSleepingOrShuttingDown()) {
            mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
        } else {
            mStackSupervisor.checkReadyForSleepLocked();
            ActivityRecord top = topStack.topRunningActivityLocked(null);
            if (top == null || (prev != null && top != prev)) {
                mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
            }
        }
    }
}
  • 發(fā)送 IDLE_NOW_MSG 消息后, Launcher 因?yàn)槭菞V形ㄒ灰粋€(gè) Activity , 所以會(huì)執(zhí)行 onStop() , 但這不是重點(diǎn). 最后會(huì)貼上執(zhí)行 onStop() 的代碼.
  • 調(diào)用了 resumeTopActivitiesLocked

接著看 resumeTopActivitiesLocked 后半段代碼

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

    // 要啟動(dòng)的 Activity
    final ActivityRecord next = topRunningActivityLocked(null);
    //... Transition相關(guān)
    // nextActivity是否已經(jīng)存在
    if (next.app != null && next.app.thread != null) {
        // 本例中Launcher點(diǎn)擊啟動(dòng), 所以不存在, 走另外一個(gè)分支
        //...
        // 狀態(tài)置位 RESUME
        next.state = ActivityState.RESUMED;
        mResumedActivity = next;
        // 應(yīng)用進(jìn)程觸發(fā) onResume()
        // 執(zhí)行后回調(diào)系統(tǒng)進(jìn)程 activityResumed
        next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                                               mService.isNextTransitionForward(), 
                                               resumeAnimOptions);
        try{
            //...
        } catch (Exception e) {
            // 這里會(huì)try catch一下, 如果在nextActivity存在的情況下執(zhí)行失敗
            // 執(zhí)行 else 時(shí)的方法
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
        }
    } else {
        // nextActivity不存在, 需要?jiǎng)?chuàng)建
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }   
}
  • 判斷要啟動(dòng)的 Activity 是否存在, 如果已經(jīng)存在的情況下, 只需要調(diào)用 onResume() 恢復(fù)頁(yè)面就可以了, 本例走不存在的分支

# ActivityStackSupervisor.startSpecificActivityLocked

void startSpecificActivityLocked(ActivityRecord r,
                                 boolean andResume, boolean checkConfig) {

    // 根據(jù) uid 和 processName查詢(xún)是否存在進(jìn)程
    // 進(jìn)程沒(méi)有被殺死就能查詢(xún)的到
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                                                        r.info.applicationInfo.uid, true);
    if (app != null && app.thread != null) {
        // 查詢(xún)到了
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                || !"android".equals(r.info.packageName)) {
                // 確保不是框架的一部分
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                               mService.mProcessStats);
            }
            // 通知該進(jìn)程啟動(dòng)目標(biāo)Activity
            // 雖然本例不進(jìn)入這個(gè)分支, 但請(qǐng)記住這個(gè)方法
            // 創(chuàng)建完成進(jìn)程后依然調(diào)用此方法
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
        }
    }

    // 沒(méi)有查詢(xún)到, 需要?jiǎng)?chuàng)建應(yīng)用進(jìn)程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                                "activity", r.intent.getComponent(), false, false, true);
}
  • 本例中進(jìn)程不存在, 需要?jiǎng)?chuàng)建

新建進(jìn)程暫時(shí)還沒(méi)有了解到, 從 Gityuan 博客的圖中了解一下.

圖片來(lái)自 Gityuan 博客

新建進(jìn)程完成后
ActivityThread.main() -> AMS.attachApplication() -> AMS.attachApplicationLocked()

# ActivityManagerService.attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread,
                                              int pid) {
    //...
    // 如果此應(yīng)用程序記錄仍附加到先前的進(jìn)程擅编,立即清理它攀细。
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }
    //...
    // 創(chuàng)建進(jìn)程時(shí), 發(fā)送了創(chuàng)建進(jìn)程超時(shí)的消息, 移除它
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
    // 獲取該進(jìn)程中的 ContentProvider
    List<ProviderInfo> providers = normalMode ? 
        generateApplicationProvidersLocked(app) : null;

    // 系統(tǒng)進(jìn)程 -> 應(yīng)用進(jìn)程
    // 進(jìn)程初次創(chuàng)建時(shí), 進(jìn)程信息為空, 
    // 這個(gè)方法將告訴該進(jìn)程具體信息
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                           profilerInfo, app.instrumentationArguments, 
                           app.instrumentationWatcher, 
                           app.instrumentationUiAutomationConnection, testMode, 
                           enableOpenGlTrace, isRestrictedBackupMode || !normalMode, 
                           app.persistent, new Configuration(mConfiguration), app.compat,
                           getCommonServicesLocked(app.isolated),
                           mCoreSettingsObserver.getCoreSettingsLocked());
    if (normalMode) {
        try {
            // 啟動(dòng)Activity
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            badApp = true;
        }
    }
   
    // 啟動(dòng)Service
    if (!badApp) {
        try {
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }
    // 啟動(dòng)廣播?
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
        } catch (Exception e) {
            badApp = true;
        }
    }
    // ...
    // 出錯(cuò)
    if (badApp) {
        handleAppDiedLocked(app, false, true);
        return false;
    }
    return true
}
  • 這個(gè)方法需要兩個(gè)分支都需要跟進(jìn), thread.bindApplication()mStackSupervisor.attachApplicationLocked(app)
  • 對(duì)清單文件中的Service和常駐廣播進(jìn)行處理

# activityThread.handleBindApplication

// AMS調(diào)用bindAppliation, 走到應(yīng)用進(jìn)程發(fā)消息給主線程, 并調(diào)用該方法
private void handleBindApplication(AppBindData data) {
    //...
    // 設(shè)置進(jìn)程名稱(chēng), 剛創(chuàng)建進(jìn)程時(shí)名字為 <pre_initialized>
    Process.setArgV0(data.processName);
    
    //獲取LoadedApk對(duì)象
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    
    //...

    if (data.instrumentationName != null) {
        // 正常情況下為空
    } else {
        mInstrumentation = new Instrumentation();
    }
    
    // 創(chuàng)建Application
    // 創(chuàng)建ContextImpl, 并執(zhí)行Application的attachBaseContext,
    Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    
    // 安裝本Package中攜帶的ContentProvider
    if (!data.restrictedBackupMode) {
        List<ProviderInfo> providers = data.providers;
        if (providers != null) {
            installContentProviders(app, providers);
            mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
        }
    }
    // 執(zhí)行Application的 onCreate()
    mInstrumentation.callApplicationOnCreate(app);
}
  • 創(chuàng)建 Application , 安裝 ContentProvider , Application 的生命周期方法

bindApplication 這條分支走完了.

ActivitySupervisor. attachApplicationLocked

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    // ...
    // 找到焦點(diǎn)Stack的棧頂Activity
    ActivityRecord hr = stack.topRunningActivityLocked(null);
    if (hr != null) {
        if (hr.app == null && app.uid == hr.info.applicationInfo.uid
            && processName.equals(hr.processName)) {
            try {
                // 和上面已經(jīng)存在進(jìn)程情況下一樣的方法
                if (realStartActivityLocked(hr, app, true, true)) {
                    didSomething = true;
                }
            } catch (RemoteException e) {}
        }
    }
    return didSomething;
}
  • 進(jìn)程及進(jìn)程的 Application 創(chuàng)建完畢, 該啟動(dòng)對(duì)應(yīng)的 Activity 了.

# ActivityStackSupervisor.realStartActivityLocked

final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
    int idx = app.activities.indexOf(r);
    if (idx < 0) {
        app.activities.add(r);
    }
    
    // 系統(tǒng)進(jìn)程 -> 應(yīng)用進(jìn)程
    // 調(diào)用 ApplicationThread 的 scheduleLaunchActivity() 方法
    // 依次調(diào)用 onCreate, onStart, onResume
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                                      System.identityHashCode(r), r.info, new 
                                      Configuration(mService.mConfiguration),
                                      new Configuration(stack.mOverrideConfig), r.compat, 
                                      r.launchedFromPackage,
                                      task.voiceInteractor, app.repProcState, r.icicle, 
                                      r.persistentState, results,
                                      newIntents, !andResume, 
                                      mService.isNextTransitionForward(), profilerInfo);
    
    //...
    // 本例中 andResume 為true
    if (andResume) {
        // 不容忽視的方法
        stack.minimalResumeActivityLocked(r);
    }   
}
  • 回到應(yīng)用進(jìn)程調(diào)用, scheduleLaunchActivity 這個(gè)方法會(huì)依次調(diào)用 Activity 的, onCreate , onStart , onResume .
  • 還有重要的一點(diǎn)是 stack.minimalResumeActivityLocked(r) 這個(gè)方法不容忽視, 等啟動(dòng)代碼分析完后在分析它.

ApplicationThread.scheduleLaunchActivity -> ActivityThread.handleLaunchActivity

# ActivityThread.handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //...
    // 創(chuàng)建 Activity, 并調(diào)用 onCreate, onStart
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        //...
        // 調(diào)用 onResume
        handleResumeActivity(r.token, false, r.isForward,
                             !r.activity.mFinished && !r.startsNotResumed);
    }
}

# ActivityThread. performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor);
    // 這個(gè)變量控制是否調(diào)用了Activity.onCreate(), 
    // Activity.onCreate()里會(huì)把mCalled賦為true
    activity.mCalled = false;
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        // 調(diào)用onCreate()
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    // 沒(méi)有調(diào)用父類(lèi)的onCreate , 拋異常
    if (!activity.mCalled) {
        throw new SuperNotCalledException(
            "Activity " + r.intent.getComponent().toShortString() +
            " did not call through to super.onCreate()");
    }
    if (!r.activity.mFinished) {
        // 調(diào)用 onStart()
        activity.performStart();
        r.stopped = false;
    }
}

# ActivityThread. handleResumeActivity

final void handleResumeActivity(IBinder token,
                                boolean clearHide, boolean isForward, boolean reallyResume) {
    // ...
    // 調(diào)用Activity的 onResume 方法
    ActivityClientRecord r = performResumeActivity(token, clearHide);
    if (r != null) {
        // ...
        if (!r.onlyLocalRequest) {
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            // 主線發(fā)送閑置消息, ***重要***
            Looper.myQueue().addIdleHandler(new Idler());
        }
        r.onlyLocalRequest = false;
        // Tell the activity manager we have resumed.
        if (reallyResume) {
            try {
                // 回調(diào)AMS, resume調(diào)用完畢, 只是修改兩個(gè)變量不探討
                ActivityManagerNative.getDefault().activityResumed(token);
            } catch (RemoteException ex) {
            }
        }
    } 
    // ...
}
  • Looper.myQueue().addIdleHandler(new Idler()) 先記住該方法

# ActivityStack.minimalResumeActivityLocked

void minimalResumeActivityLocked(ActivityRecord r) {
    r.state = ActivityState.RESUMED;
    r.stopped = false;
    mResumedActivity = r;
    r.task.touchActiveTime();
    mRecentTasks.addLocked(r.task);
    // 看下面
    completeResumeLocked(r);
    mStackSupervisor.checkReadyForSleepLocked();
    setLaunchTime(r);
}

private void completeResumeLocked(ActivityRecord next) {
    next.idle = false;
    next.results = null;
    next.newIntents = null;

    // 設(shè)置空閑超時(shí)
    // 發(fā)送給 AMS 進(jìn)程的handler一個(gè)空閑超時(shí)的消息
    // 在 應(yīng)用進(jìn)程的 Handler在空閑時(shí), 會(huì)調(diào)用 系統(tǒng)進(jìn)程的 activityIdle()
    // 在該方法中執(zhí)行 finish或stop等方法, 具體總結(jié)后在摘代碼
    mStackSupervisor.scheduleIdleTimeoutLocked(next);
}

至此上面記錄的三個(gè)重要函數(shù)在重新列一下

  • 系統(tǒng)進(jìn)程 -> mStackSupervisor.scheduleIdleLocked()
  • 應(yīng)用進(jìn)程 -> Looper.myQueue().addIdleHandler(new Idler())
  • 系統(tǒng)進(jìn)程 -> mStackSupervisor.scheduleIdleTimeoutLocked(next)

這三個(gè)方法最終都會(huì)調(diào)用 ActivitySupervisor.activityIdleInternalLocked
最后一個(gè)方法會(huì)執(zhí)行延遲10秒發(fā)送, 這種方法在上述代碼中提過(guò)一次

# ActivitySupervisor.activityIdleInternalLocked

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
                                                Configuration config) {
    // 要執(zhí)行Stop的集合
    ArrayList<ActivityRecord> stops = null;
    // 要執(zhí)行Finish的集合
    ArrayList<ActivityRecord> finishes = null;
    ArrayList<UserState> startingUsers = null;
    boolean booting = false;
    boolean activityRemoved = false;

    ActivityRecord r = ActivityRecord.forTokenLocked(token);
    if (r != null) {
        // 移除超時(shí)消息
        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
    }

    // mStoppingActivities集合中, 將即將可見(jiàn)的Activity除外
    stops = processStoppingActivitiesLocked(true);
    NS = stops != null ? stops.size() : 0;
    if ((NF = mFinishingActivities.size()) > 0) {
        finishes = new ArrayList<>(mFinishingActivities);
        mFinishingActivities.clear();
    }

    // Stop any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NS; i++) {
        r = stops.get(i);
        final ActivityStack stack = r.task.stack;
        if (stack != null) {
            if (r.finishing) {
                // 如果要執(zhí)行 stop的狀態(tài)為finish, 立即結(jié)束
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
            } else {
                // 否則執(zhí)行 stop
                stack.stopActivityLocked(r);
            }
        }
    }

    // Finish any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NF; i++) {
        r = finishes.get(i);
        final ActivityStack stack = r.task.stack;
        if (stack != null) {
            // 如果有要結(jié)束的Activity, 結(jié)束掉
            activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
        }
    }

    // 如果有被移除的 Activity, 執(zhí)行resumeTopActivitiesLocked
    if (activityRemoved) {
        resumeTopActivitiesLocked();
    }

    return r;
}

至此整個(gè)Activity啟動(dòng)流程結(jié)束了.
需要注意的是 resumeTopActivitiesLocked() , 只要操作 Activity , 就會(huì)有 Pause 的界面和 Resume 的界面, 一般情況下 Resume 會(huì)等待 Pause 完后執(zhí)行 . 所以調(diào)用 resumeTopActivitiesLocked 的地方特別多, 要注意在哪里返回, 在哪里繼續(xù)執(zhí)行 .

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市爱态,隨后出現(xiàn)的幾起案子谭贪,更是在濱河造成了極大的恐慌,老刑警劉巖锦担,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俭识,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡洞渔,警方通過(guò)查閱死者的電腦和手機(jī)套媚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)缚态,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人堤瘤,你說(shuō)我怎么就攤上這事玫芦。” “怎么了本辐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵桥帆,是天一觀的道長(zhǎng)糯而。 經(jīng)常有香客問(wèn)我流码,道長(zhǎng),這世上最難降的妖魔是什么确丢? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任茫多,我火速辦了婚禮祈匙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘天揖。我一直安慰自己菊卷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布宝剖。 她就那樣靜靜地躺著洁闰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪万细。 梳的紋絲不亂的頭發(fā)上扑眉,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音赖钞,去河邊找鬼腰素。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雪营,可吹牛的內(nèi)容都是我干的弓千。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼献起,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼洋访!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起谴餐,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤姻政,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后岂嗓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體汁展,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了食绿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侈咕。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖器紧,靈堂內(nèi)的尸體忽然破棺而出耀销,到底是詐尸還是另有隱情,我是刑警寧澤品洛,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布树姨,位于F島的核電站摩桶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏硝清。R本人自食惡果不足惜辅斟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一芳撒、第九天 我趴在偏房一處隱蔽的房頂上張望笔刹。 院中可真熱鬧,春花似錦冬耿、人聲如沸舌菜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)日月。三九已至,卻和暖如春缤骨,著一層夾襖步出監(jiān)牢的瞬間山孔,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工荷憋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留台颠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像串前,于是被迫代替她去往敵國(guó)和親瘫里。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容