Activity启动2-startActivityMayWait方法

我们从上一节分析参数开始最终达到:

result = mInterface.startActivityAndWait(null, null, intent, mimeType,
                                         null, null, 0, mStartFlags, profilerInfo,
                                         options != null ? options.toBundle() : null, mUserId);

此时我们先承上启下的分析参数:

参数含义
IApplicationThread caller调用者进程控制器null
String callingPackage调用者所在包名null
Intent intent调用者的意图intent
String resolvedTypeprovider中getType返回的值,有些页面可以处理这种urimimeType
IBinder resultTo接受结果的activitytRecord(binder对象)null
String resultWho用户自定义的字符串,调用完毕会传回去null
int requestCode用户自定义的code,调用完毕会传回去0
int startFlags启动标志mStartFlags
ProfilerInfo profilerInfo统计数据profilerInfo
Bundle bOptions其他启动参数 可能是从父activity继承的options.toBundle()
int userIduserIdmUserId

ActvitiyManagerService.java

@Override
public final WaitResult startActivityAndWait(IApplicationThread caller, 
                                             String callingPackage,
                                             Intent intent, String resolvedType,
                                             IBinder resultTo, String resultWho, 
                                             int requestCode,
                                             int startFlags, ProfilerInfo profilerInfo, 
                                             Bundle bOptions, int userId) {
    enforceNotIsolatedCaller("startActivityAndWait");
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), 
                                                Binder.getCallingUid(),
                                                userId, false, ALLOW_FULL_ONLY, 
                                                "startActivityAndWait", null);
    WaitResult res = new WaitResult();
    // TODO: Switch to user app stacks here.
    mActivityStarter.startActivityMayWait(caller, -1, callingPackage, 
                                          intent, resolvedType,
                                          null, null, resultTo, 
                                          resultWho, requestCode, startFlags, 
                                          profilerInfo, res, null,
                                          bOptions, false, userId, null, 
                                          "startActivityAndWait");
    return res;
}
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 globalConfig, Bundle bOptions, 
                               boolean ignoreTargetSecurity, int userId,
                               TaskRecord inTask, String reason) {
    	//intent不能传递文件句柄
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
    	//指定-n或者通过查找PKMS中的注册表
        boolean componentSpecified = intent.getComponent() != null;
    	//拷贝两个intent,一个是临时,一个是防止修改之后无法还原
        final Intent ephemeralIntent = new Intent(intent);
    	intent = new Intent(intent);
    	//当有对应组件并且传递的数据不为null,并且action也就是指定了-a参数是android.intent.action.VIEW
    	//并且是安装程序对应的Activity
    	//反正走不到这里
        if (componentSpecified
                && intent.getData() != null
                && Intent.ACTION_VIEW.equals(intent.getAction())
                && mService.getPackageManagerInternalLocked()
                        .isInstantAppInstallerComponent(intent.getComponent())) {、
            intent.setComponent(null /*component*/);
            componentSpecified = false;
        }
	    //利用PKMS解析满足Intent等参数要求的信息,内部包含了四大组件等从清单文件中声明的信息
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
    	//当没有得到ResolveInfo时
        if (rInfo == null) {
            UserInfo userInfo = mSupervisor.getUserInfo(userId);
            //通过isManagedProfile()方法来判断这份UserInfo是否只是一个profile(Android中允许一个用户还拥有另一份profile)
            if (userInfo != null && userInfo.isManagedProfile()) {
                UserManager userManager = UserManager.get(mService.mContext);
                boolean profileLockedAndParentUnlockingOrUnlocked = false;
                long token = Binder.clearCallingIdentity();
                try {
                    UserInfo parent = userManager.getProfileParent(userId);
                    profileLockedAndParentUnlockingOrUnlocked = (parent != null)
                            && userManager.isUserUnlockingOrUnlocked(parent.id)
                            && !userManager.isUserUnlockingOrUnlocked(userId);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
                if (profileLockedAndParentUnlockingOrUnlocked) {
                    rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                            PackageManager.MATCH_DIRECT_BOOT_AWARE
                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
                }
            }
        }
   	    //上面是有关多用户的一段逻辑
        // 通过ResolveInfo得到目标Activity的信息.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    	//得到ActivityOptions,有关这个就是通过--task,--stack,--display等设置的一些额外参数
        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
    	//来了一把AMS的锁
        synchronized (mService) {
            //得到调用的Pid和Uid
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            int callingPid;
            if (callingUid >= 0) {
                callingPid = -1;
            } else if (caller == null) {
                callingPid = realCallingPid;
                callingUid = realCallingUid;
            } else {
                callingPid = callingUid = -1;
            }
            //得到当前的栈
            final ActivityStack stack = mSupervisor.mFocusedStack;
            //false
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;
            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                    "Starting activity when config will change = " + stack.mConfigWillChange);
            //清除Pid和Uid,用于安全检查
            final long origId = Binder.clearCallingIdentity();
            //如果ActivityRecord不为null,ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE标记,意味着调用者App是属于heavy-weight process
            if (aInfo != null &&
                    (aInfo.applicationInfo.privateFlags
                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                //进程名等于Application中的包名
                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                    //得到重量级进程的记录,当前运行的
                    final ProcessRecord heavy = mService.mHeavyWeightProcess;
                    //当前运行的重量级进程与要启动的不符合
                    if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
                            || !heavy.processName.equals(aInfo.processName))) {
                        int appCallingUid = callingUid;
                        if (caller != null) {
                           	//得到调用着的进程记录
                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
                            if (callerApp != null) {
                                appCallingUid = callerApp.info.uid;
                            } else {
                                Slog.w(TAG, "Unable to find app for caller " + caller
                                        + " (pid=" + callingPid + ") when starting: "
                                        + intent.toString());
                                ActivityOptions.abort(options);
                                return ActivityManager.START_PERMISSION_DENIED;
                            }
                        }

                        IIntentSender target = mService.getIntentSenderLocked(
                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
                                appCallingUid, userId, null, null, 0, new Intent[] { intent },
                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
                                        | PendingIntent.FLAG_ONE_SHOT, null);
					  //新的Intent
                        Intent newIntent = new Intent();
                        if (requestCode >= 0) {
                            // Caller is requesting a result.
                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
                        }
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
                                new IntentSender(target));
                        //当前重量级进程的ActivityRecord数量大于0
                        if (heavy.activities.size() > 0) {
                            //得到第一个Activity,将名字和栈set进新的Intent中
                            ActivityRecord hist = heavy.activities.get(0);
                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
                                    hist.packageName);
                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
                                    hist.getTask().taskId);
                        }
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
                                aInfo.packageName);
                        newIntent.setFlags(intent.getFlags());
                        //新intent的名称
                        newIntent.setClassName("android",
                                HeavyWeightSwitcherActivity.class.getName());
                        intent = newIntent;
                        resolvedType = null;
                        caller = null;
                        callingUid = Binder.getCallingUid();
                        callingPid = Binder.getCallingPid();
                        componentSpecified = true;
                        rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
                        aInfo = rInfo != null ? rInfo.activityInfo : null;
                        if (aInfo != null) {
                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
                        }
                    }
                }
            }
            //创建新的ActivityRecord
            final ActivityRecord[] outRecord = new ActivityRecord[1];
            //执行startActivityLocked
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
            //设置pid,uid,权限校验相关
            Binder.restoreCallingIdentity(origId);
            //false
            if (stack.mConfigWillChange) { mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                        "updateConfiguration()");
                stack.mConfigWillChange = false;
                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                        "Updating to new configuration after starting activity.");
                mService.updateConfigurationLocked(globalConfig, null, false);
            }
            //当结果不为null
            if (outResult != null) {
                outResult.result = res;
                //并且成功启动
                //目标Activity要运行在一个新的应用进程中,因此需要等待应用进程正常启动并处理相关请求
                if (res == ActivityManager.START_SUCCESS) {
                    mSupervisor.mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            //一直等待,直到outResult显示Activity对应的Task成为front task
                            mService.wait();
                        } catch (InterruptedException e) {
                        }
                        //如果请求结果不是START_TASK_TO_FRONT,并且没有超时,并且调用方不是null则等待
                    } while (outResult.result != START_TASK_TO_FRONT
                            && !outResult.timeout && outResult.who == null);
                    if (outResult.result == START_TASK_TO_FRONT) {
                        res = START_TASK_TO_FRONT;
                    }
                }
                if (res == START_TASK_TO_FRONT) {
                    final ActivityRecord r = outRecord[0];
                    if (r.nowVisible && r.state == RESUMED) {
                        outResult.timeout = false;
                        outResult.who = r.realActivity;
                        outResult.totalTime = 0;
                        outResult.thisTime = 0;
                    } else {
                        outResult.thisTime = SystemClock.uptimeMillis();
                        //Activity对应的task拉到前台后,一直要等到该界面被加载
                        mSupervisor.waitActivityVisible(r.realActivity, outResult);
                        do {
                            try {
                                mService.wait();
                            } catch (InterruptedException e) {
                            }
                        } while (!outResult.timeout && outResult.who == null);
                    }
                }
            }
        }
}

小结这个方法;

  • 解析出与Intent相匹配的ActivityInfo。
  • 得到启动该Activity的Task,前台Task。
  • 通过startActivityLocked启动Activity
  • 对返回值进行处理,因为使用-W的参数,所以等待Activity被启动
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值