【筆記】ActivityManagerService 啓動activity

https://blog.csdn.net/csdn_of_coder/article/details/78024696

 

 

1.Activity向AMS 發起請求啓動App 

1.1 AMS 啓動Activity 流程

AMS 調用startActivity() 來啓動APP:

    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) {

        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }

AMS.startActivity() ---> AMS.startActivityAsUser():

    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) {
        // 如果是膈應的應用,不允許打開其他app的activity
        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.startActivityAsUser() ---> ActivityStackSupervisor.startActivityMayWait()

final int startActivityMayWait(
            IApplicationThread caller,//AMS通過這個參數可以和發起者進行交互
            int callingUid,//發起者uid
            String callingPackage,//發起者包名
            Intent intent, // 啓動activity的intent
            String resolvedType, // intent的類型,也就是MIME type
            IVoiceInteractionSession voiceSession,
            IVoiceInteractor voiceInteractor,
            IBinder resultTo,//用於接收startActivityForResult的結果,launcher啓動app這種情景下沒有用,爲null
            String resultWho,
            int requestCode,//這個是調用者來定義其意義,若值大於等於0,則AMS內部保存該值並通過onActivityResult返回調用者,這裏爲-1
            int startFlags,// 傳入的爲0
            ProfilerInfo profilerInfo,
            WaitResult outResult,
            Configuration config,
            Bundle options,
            boolean ignoreTargetSecurity,
            int userId,
            IActivityContainer iContainer,  // 傳入的爲null
            TaskRecord inTask)/ // 傳入爲null
{

    ... ...
 
    //創建一個新的intent,方便後面進行改變
    intent = new Intent(intent);

    //創建保存activity 信息的activityInfo 對象
    ActivityInfo aInfo =resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);

    ... ...
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                    componentSpecified, null, container, inTask);
    ... ...
            if (outResult != null) {
                 ... ...
                 mService.wait(); //等待應用進程的activity啓動完成
                 ... ...
            }

    ... ...
            if (res == ActivityManager.START_SUCCESS) {
                ... ...
                 mService.wait();
                ... ...
            } else if (res == ActivityManager.START_TASK_TO_FRONT) {
                if (r.nowVisible && r.state == RESUMED) {
                
                } else {
                    mService.wait();
                }

            }


}

ActivityStackSupervisor.startActivityMayWait 調用ActivityStackSupervisor.resolveActivity 獲取需要啓動的activity 所屬的pkg信息。

ctivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
            ProfilerInfo profilerInfo, int userId) {
        // Collect information about the target of the Intent.
        ActivityInfo aInfo;
        try {
            ResolveInfo rInfo =
                AppGlobals.getPackageManager().resolveIntent(
                        intent, resolvedType,PackageManager.MATCH_DEFAULT_ONLY| 
                        ActivityManagerService.STOCK_PM_FLAGS, userId);
            aInfo = rInfo != null ? rInfo.activityInfo : null;
        } catch (RemoteException e) {
            aInfo = null;
        }

        ... ...
        return aInfo;
    }

  

startActivityAsUser() 的主要目的是進行權限檢查,檢查是否被隔離,是的話,不允許調用別的app的activity。

startActivityMayWait()方法主要是利用傳進去的intent去向PKMS 獲取需要 啓動的app 的信息,存儲在aIndo 中。

 

ActivityStackSupervisor.resolveActivity --->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) {

        int err = ActivityManager.START_SUCCESS;

        //調用進程對應的ProcessRecord實例,這裏是Launcher進程
        ProcessRecord callerApp = null;
        ... ...
        ActivityRecord sourceRecord = null; //指向Launcher組件的一個ActivityRecord實例,它作爲source端
        ActivityRecord resultRecord = null;

        ... ...
        
        //根據之前得到的一些信息,創建一個代表將要啓動的Activity的ActivityRecord對象
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, this, container, options);

       ... ... 
        try {
            mService.mWindowManager.deferSurfaceLayout();

            //繼續調用startActivityUnchecked();doResume爲true
            err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true, options, inTask);

        } finally  {
            mService.mWindowManager.continueSurfaceLayout();
        }



}

 獲取此Activity 的信息,初始化爲一個 ActivityRecord對象,它代表了當前需要啓動的Activity在AMS中的存在形式。

繼續調用startActivityUnchecked 函數

 

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