Framework学习笔记——launcher的启动过程

653 阅读4分钟

一、Android系统架构

android系统架构图.png 如图所示,Android系统架构分为五层,从上到下分别是:应用层,应用架构层,系统运行库层,硬件抽象层和内核层。我们应用开发者接触的做多的两层就是应用层和应用架构层了。学习这两层对我们开发应用有极大的帮助性。

二、Android系统的启动流程

①启动电源:当我们长按手机的开机按钮时引导芯片代码从预定义的得放开始执行,加载引导程序BootLoader到RAM,然后执行。

②引导程序BootLoader:BootLoader是在Android操作系统开始运行前的一个小程序,他的作用是负责拉起整个系统。

③Linux内核启动:当内核启动时,设置缓存、被保存储器、计划列表、加载驱动。当内核完成系统设置时,它首先在系统文件中寻找init.rc文件,并启动。

④init进程启动:初始化和启动属性服务,并且启动Zygote进程。

⑤Zygote进程启动:创建java虚拟机并为java虚拟机注册jni方法,创建服务器Socket,启动SystemServer。

⑥SystemServer进程启动:启动Binder线程池和SystemServiceManager,并且启动各种系统服务。

⑦Launcher启动:被SystemServer启动的ActivityManagerService会启动Launcher,Launcher启动后会将已经安装的App的快捷图标显示在界面上。

三、Launcher启动

在SystemServer启动过程中启动三种服务,分别是引导服务、核心服务和其他服务。其中核心服务包括之前介绍的AMS,启动完AMS后AMS会启动Launcher,Launcher启动后会将已安装的应用图标显示在界面上。

mActivityManagerService.systemReady(() -> {
    Slog.i(TAG, "Making services ready");
    traceBeginAndSlog("StartActivityManagerReadyPhase");
    mSystemServiceManager.startBootPhase(
            SystemService.PHASE_ACTIVITY_MANAGER_READY);
    traceEnd();
    traceBeginAndSlog("StartObservingNativeCrashes");
    try {
        mActivityManagerService.startObservingNativeCrashes();
    } catch (Throwable e) {
        reportWtf("observing native crashes", e);
    }
    traceEnd();
    ·····
    }

AMS的systemReay()方式是启动Launcher的入口,这里用的是java的Lambda表达式。

public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {   
synchronized(this) {
    if (mSystemReady) {
        // If we're done calling all the receivers, run the next "boot phase" passed in
        // by the SystemServer
        if (goingCallback != null) {
            goingCallback.run();
        }
        return;
    }
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
}

最终会走到mStackSupervisor的resumeFocusedStackTopActivity()中,其中mStackSupervisor的类型是ActivityStackSupervisor,他是Activity栈的管理者。

boolean resumeFocusedStackTopActivityLocked() {
    return resumeFocusedStackTopActivityLocked(null, null, null);
}

接下来ActivityStackSupervisor会调用自身的resumeFocusedStackTopActivityLocked()方法。

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.state == RESUMED) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }
    return false;
}

最终回到用到变量mFocusedStack的resumeTopActivtyUncheckedlocked()方法。 mFocusedStack是ActivityStack类型,它是描述一个Acitivty栈的类。

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    // When resuming the top activity, it may be necessary to pause the top activity (for
    // example, returning to the lock screen. We suppress the normal pause logic in
    // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end.
    // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure
    // any necessary pause logic occurs.
    mStackSupervisor.checkReadyForSleepLocked();

    return result;
}

之后会调用ActivityStack的resumeTopActivityInnerLocked()方法并且该方法会返回一个布尔类型的调用结果。

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }
if (prevTask != null && prevTask.getStack() == this &&
        prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
    if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
    if (prevTask == nextTask) {
        prevTask.setFrontOfTask();
    } else if (prevTask != topTask()) {
        // This task is going away but it was supposed to return to the home stack.
        // Now the task above it has to return to the home task instead.
        final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
        mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
    } else if (!isOnHomeDisplay()) {
        return false;
    } else if (!isHomeStack()){
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Launching home next");
        return isOnHomeDisplay() &&
                mStackSupervisor.resumeHomeStackTask(prev, "prevFinished"); //重点
    }
}
    }

之后又回到ActivtyStackSupervisor的resumeHomeStackTask()方法。


boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }

    if (prev != null) {
        prev.getTask().setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
    }

    mHomeStack.moveHomeStackTaskToTop();
    ActivityRecord r = getHomeActivity();
    final String myReason = reason + " resumeHomeStackTask";

    // Only resume home activity if isn't finishing.
    if (r != null && !r.finishing) {
        moveFocusableActivityStackToFrontLocked(r, myReason);
        return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
    }
    return mService.startHomeActivityLocked(mCurrentUser, myReason);//重要
}

最后调用了mService.startHomeActivityLocked()方法。这里的mService的类型就是ActivityManagerService。

boolean startHomeActivityLocked(int userId, String reason) {
// 判断是否工厂模式
    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
            && mTopAction == null) {
        // We are running in factory test mode, but unable to find
        // the factory test app, so just sit around displaying the
        // error message and don't try to start anything.
        return false;
    }
    // 获取需要的Intent
    Intent intent = getHomeIntent();
    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) {
            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);
        }
    } else {
        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
    }

    return true;
}

这个方法它会获取Activity所需的Intent和判断它的工厂模式是什么类型,最后它会找需要启动的Activity是否已经存在进程。最终它会调用ActivityStarter的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 /*container*/, null /*inTask*/, "startHomeActivity: " + reason);
    if (mSupervisor.inResumeTopActivity) {
        // 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();
    }
}

在启动Activity之前它会先将Activity移入Activity的栈当中。之后就是Activity的启动流程了。在这Launcher的启动流程就结果了,Launcher启动之后再Launcher.java中会将已经安装的应用程序图标显示在桌面上,每一个图标都代表了一个app,点击图标之后就是启动应用程序的过程,也是startActivity的启动过程。