Android8.1 Launcher3启动源码解析之第一个Activity启动

本文深入解析Android8.1系统中Launcher3的启动源码,从AMS启动Launcher到Activity的启动过程,包括ActivityStarter的startHomeActivityLocked、startActivityLocked等方法,再到ActivityStackSupervisor中的resumeFocusedStackTopActivityLocked等关键步骤,最后在AMS中创建Activity线程,阐述了Launcher启动的关键流程。
摘要由CSDN通过智能技术生成

前一篇文章说了与Launcher有关的AMS启动过程,这篇文章来说一说与Launcher启动有关的Activity的启动过程

一、AMS启动Launcher

接上篇文章看AMS中启动HomeActivity的方法

boolean startHomeActivityLocked(int userId, String reason) {
  ......
    Intent intent = getHomeIntent();//获取启动Launcher的意图
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        // Don't do this if the home app is currently being
        // instrumented.
        aInfo = new ActivityInfo(aInfo);
        aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
        ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                aInfo.applicationInfo.uid, true);
        if (app == null || app.instr == null) {
 //这里app肯定是null的
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
            // For ANR debugging to verify if the user activity is the one that actually
            // launched.
            final String myReason = reason + ":" + userId + ":" + resolvedUserId;
            mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason); //开始启动laucher
        }
    } else {
        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
    }

    return true;
}

由此我们可以看ActivityStarter中的startHomeActivityLock方法

二、ActivityStarter

1、startHomeActivityLocked
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
    mSupervisor.moveHomeStackTaskToTop(reason);
    mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,
            null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,
            null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,
            null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,
            null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
            0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
            false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
            null /*inTask*/, "startHomeActivity: " + reason);
    if (mSupervisor.inResumeTopActivity) { //初始化为false
        // If we are in resume section already, home activity will be initialized, but not
        // resumed (to avoid recursive resume) and will stay that way until something pokes it
        // again. We need to schedule another resume.
        mSupervisor.scheduleResumeTopActivities();
    }
}
没啥实质性进展,就是传递默认值。看startActivityLocked方法
2、startActivityLocked
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                        ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                        ActivityRecord[] outActivity, TaskRecord inTask, String reason) {

    if (TextUtils.isEmpty(reason)) {
        throw new IllegalArgumentException("Need to specify a reason.");
    }
    mLastStartReason = reason;
    mLastStartActivityTimeMs = System.currentTimeMillis();
    mLastStartActivityRecord[0] = null;

    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask);

    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }

    // Aborted results are treated as successes externally, but we must track them internally.
    return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}

从这里看出,只是赋值了一些变量,然后直接掉startActivity方法。

3、startActivity

/** DO NOT call this method directly. Use {
   @link #startActivityLocked} instead. */
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                          String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                          IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                          IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                          String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                          ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                          ActivityRecord[] outActivity, TaskRecord inTask) {
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle
            = options != null ? options.popAppVerificationBundle() : null;

    ProcessRecord callerApp = null;
    if (caller != null) { //此时caller为
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            Slog.w(TAG, "Unable to find app for caller " + caller
                    + " (pid=" + callingPid + ") when starting: "
                    + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }

    final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值