startActivity流程

1. startActivity流程图

调用方Activity1通过调用startActivity()跳转到Activity2的流程图如下所示,后面将对其中重要步骤进行详细分析

2. startActivityMayWait()

startActivityMayWait()函数代码很长,其核心工作主要分为5个步骤:


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) 


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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值