android AMS—— Activity的啟動一

Activity的啟動由APP端發(fā)起,通過Binder通訊進入系統(tǒng)端的AMS。


Acitivity的啟動.png

一、APP端發(fā)起

從APP端點擊應用打開窗口調用StartActivity開始流程經(jīng)過Instrumentation. execStartActivity中ActivityManager.getService()獲得AMS IBinder客戶端,并與AMS進行交互,進入到AMS中的startActivity。

二、AMS端

1、ActivityStartController&&ActivityStarter

從名字上看兩者,ActivityStartController應該是作為ActivityStarter的Control類存在的,在AMS.startActivityAsUser中通過ActivityStartController來啟動創(chuàng)建Activity的流程

/*AMS.java*/
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");

        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

    }

從代碼調用中可以看出其類似 建造者設計模式的方式,其ActivityStartController中采用了通過ActivityStarter.DefaultFactory采用享元模式共享ActivityStarter對象池。


ActivityStater.png

通過ActivityStartController.obtainStarter從mFactory中的ActivityStarter線程池中獲取已有或者新創(chuàng)建一個ActivityStater對象,通過鏈式調用進行賦值后調用execute執(zhí)行。進入ActivityStater.startActivityMayWait。
ActivityStarter.startActivityMayWait:主要解析出與Intent相匹配的ActivityInfo

  • 從PackageManagerService準備activity需要的數(shù)據(jù)。查找PMS中已有的ResolveInfo,通過intent如果匹配到多個則用戶選擇,沒匹配到則從啟動中獲取ResolveInfo。并通過通過PMS的getActivityInfo讀取ActivityInfo。
  • 對重量進程處理
  • 進入下一步啟動調用startActivity

并將解析的ActivityInfo信息傳入到startActivity()方法為目標Activity準備好了ActivityRecord,并將新創(chuàng)建的ActivityRecord作為參數(shù)傳入另一個startActivity,再進入startActivityUnchecked,
startActivityUnchecked: 該函數(shù)主要針對Activity棧進行處理,通過對intent中flag的分析選擇TaskRecord以及ActivityStack,或者創(chuàng)建TaskRecord以及ActivityStack > 創(chuàng)建流程另外分析吧)

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
         //注釋1: 整個參數(shù)賦值給ActivityStarter的全局變量
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        //注釋2: 計算Task的flag
        computeLaunchingTaskFlags();
        //注釋3:獲取調用方的Activity棧
        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);

        ActivityRecord reusedActivity = getReusableIntentActivity();
        ......
}

注釋1:setInitialState 整個參數(shù)賦值給ActivityStarter的全局變量,并對Intent中的flag進行一些處理,其中主要處理FLAG_ACTIVITY_NEW_DOCUMENT的

2、ActivityStack.resumeTopActivityInnerLocked

Activity-pause.png

ActivityStart中通過ActivityStackSupervisor.resumeFocusedStackTopActivityLocked處理mFocusedStack.resumeTopActivityUncheckedLocked進入到FocusStatck的切換處理resumeTopActivityInnerLocked:
resumeTopActivityInnerLocked該函數(shù)主要完成:

  • 調用該ActivityStatck中的棧內所有Activity的onPause
    從上圖可以看出通過ActivityStackSupervisor.pauseBackStacks循環(huán)獲取ActivityStackSupervisor中的ActivityDisplay中的ActivityStack,然后調用每個ActivityStack的startPausingLocked方法
    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {
    ......
                mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                        PauseActivityItem.obtain(prev.finishing, userLeaving,
                                prev.configChangeFlags, pauseImmediately));

    ......
}
  • 檢查ActivityRecord,若為復用對象,則通過創(chuàng)建ClientTransaction對象以及NewIntentItem、ResumeActivityItem事務完成onResume的調用
if (next.app != null && next.app.thread != null) {
  //找到下一個需要啟動的對象已經(jīng)存在,則只需要resume
  ......
  final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
                            next.appToken);
  ArrayList<ResultInfo> a = next.results;
   if (a != null) {
            final int N = a.size();
           if (!next.finishing && N > 0) {
                 transaction.addCallback(ActivityResultItem.obtain(a));
              }
     }

    if (next.newIntents != null) {
            transaction.addCallback(NewIntentItem.obtain(next.newIntents,
                                false /* andPause */));
     }
   transaction.setLifecycleStateRequest(
                            ResumeActivityItem.obtain(next.app.repProcState,
                                    mService.isNextTransitionForward()));
 ......
 }else{
    //下一個對象為空,則說明新建的ActivityRecord并沒有與APP端綁定
    mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
  • ActivityStackSupervisor.startSpecificActivityLocked
    對于新開一個Activity,最終是進入該函數(shù),由該函數(shù)進入realStartActivityLocked開始真正的新Activity的生命周期的流程。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容