Android Framework:Launcher启动

Android Framework:Launcher启动

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

/frameworks/base/services/java/com/android/server/SystemServer.java,如果了解了SystemServer.java这个类的话,就应该知道它的主要工作就是启动一系列的重要Service,找到startOtherServices方法,拉到最后,可以找到如下代码:

java 复制代码
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();
    ·····
    }

可以看到,在这里SystemServer调用了ActivityManagerServicesystemReady方法,进入此方法,其它的先不管,找到这段代码:

java 复制代码
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栈的管理者。

java 复制代码
boolean resumeFocusedStackTopActivityLocked() {
    return resumeFocusedStackTopActivityLocked(null, null, null);
}

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

java 复制代码
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栈的类。

java 复制代码
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()方法并且该方法会返回一个布尔类型的调用结果。

java 复制代码
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()方法。

java 复制代码
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。

java 复制代码
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()方法。

相关推荐
阿智@117 分钟前
Node.js 助力前端开发:自动化操作实战
运维·前端·node.js·自动化
编程洪同学9 分钟前
Spring Boot 中实现自定义注解记录接口日志功能
android·java·spring boot·后端
m0_7482517236 分钟前
前端入门之VUE--ajax、vuex、router,最后的前端总结
前端·vue.js·ajax
上等猿40 分钟前
Ajax笔记
前端·笔记·ajax
Amo 672942 分钟前
css 编写注意-1-命名约定
前端·css
程序猿online1 小时前
nvm安装使用,控制node版本
开发语言·前端·学习
web Rookie2 小时前
React 中 createContext 和 useContext 的深度应用与优化实战
前端·javascript·react.js
男孩122 小时前
react高阶组件及hooks
前端·javascript·react.js
m0_748251722 小时前
DataOps驱动数据集成创新:Apache DolphinScheduler & SeaTunnel on Amazon Web Services
前端·apache
珊珊来吃2 小时前
EXCEL中给某一列数据加上双引号
java·前端·excel