天天看點

startActivity流程

1. startActivity流程圖

調用方Activity1通過調用startActivity()跳轉到Activity2的流程圖如下所示,後面将對其中重要步驟進行詳細分析

startActivity流程

2. startActivityMayWait()

startActivityMayWait()函數代碼很長,其核心工作主要分為5個步驟:

startActivity流程

1)确定目标Activity

2)擷取目标Activity的資訊

3)判斷目标Activity所屬程序是否是重量級的

4)調用startActivityLocked()執行啟動操作

5)如果onResult不為空,需将結果寫入變量中

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, String profileFile,
            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
            Bundle options, int userId)
{
        // step1. 确定目标Activity
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        boolean componentSpecified = intent.getComponent() != null;
        // Don't modify the client's object!
        intent = new Intent(intent);

        // step2. 擷取目标Activity的資訊
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
                profileFile, profileFd, userId);

        synchronized (mService) {
            ……
            if (mMainStack && aInfo != null &&
                    (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                    if (mService.mHeavyWeightProcess != null &&
                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
                        ……
                        //step3.判斷是否是重量級程序
                        if (mService.mHeavyWeightProcess.activities.size() > 0) {
                            ……
                        }
                        ……
                }
            }
            //step4.調用startActivityLocked()執行啟動工作</span>
            int res = startActivityLocked(caller, intent, resolvedType,
                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
                    startFlags, options, componentSpecified, null);
            //step5.outResult不為空時,将結果寫入該變量中
            if (outResult != null) {
                ……
            }            
            return res;
        }
    }
}
           

3. startActivityLocked(1) 

startActivity流程

1)確定調用者caller的程序是存在的

2)處理FLAG_ACTIVITY_FORWARD_RESULT(這個标志具有跨程序傳遞的作用,例如:Activity1啟動了Activity2,而Activity2啟動Activity3時使用了此标志,那麼當Activity3調用setResult時,result不會像一般情況那樣傳遞給Activity2,而是傳給Activity1)

3)是否找到合适的目标Activity來處理Intent,若沒有則直接報錯傳回

4)檢查調用者是否有足夠權限來啟動指定的Activity

5)調用startActivityUncheckedLocked()處理啟動模式和Intent标志

final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
            String resultWho, int requestCode,
            int callingPid, int callingUid, int startFlags, Bundle options,
            boolean componentSpecified, ActivityRecord[] outActivity)
{
    //step1.判斷調用者caller是否為空
    if (caller != null) {
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
           callingPid = callerApp.pid;
           callingUid = callerApp.info.uid;
        } else {
           err = ActivityManager.START_PERMISSION_DENIED;
        }
   }
   ……
   //step2.處理FLAG_ACTIVITY_FORWARD_RESULT
   int launchFlags = intent.getFlags();
   if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
                && sourceRecord != null) {
      // Transfer the result target from the source activity to the new
      // one being started, including any failures.
      if (requestCode >= 0) {
         ActivityOptions.abort(options);
         return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
      }
      resultRecord = sourceRecord.resultTo;
      resultWho = sourceRecord.resultWho;
      requestCode = sourceRecord.requestCode;
      sourceRecord.resultTo = null;
      if (resultRecord != null) {
        resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
      }
   }
   //step3.判斷是否找到合适的目标Activity來處理Intent
   if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
      err = ActivityManager.START_INTENT_NOT_RESOLVED;
   }
   if (err == ActivityManager.START_SUCCESS && aInfo == null) {
      err = ActivityManager.START_CLASS_NOT_FOUND;
   }
   if (err != ActivityManager.START_SUCCESS) {
      if (resultRecord != null) {
        sendActivityResultLocked(-1,
        resultRecord, resultWho, requestCode,
        Activity.RESULT_CANCELED, null);
      }
      mDismissKeyguardOnNextActivity = false;
      ActivityOptions.abort(options);
      return err;
   }
   //step4. 檢查調用者是否有足夠權限來啟動指定的Activity
   final int startAnyPerm = mService.checkPermission(
                START_ANY_ACTIVITY, callingPid, callingUid);
   final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, callingUid,                                               aInfo.applicationInfo.uid, aInfo.exported);
   if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
      ……
   }
   //step5.調用startActivityUncheckedLocked()處理啟動模式和Intent标志
   err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
   return err;
}