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()方法。

相关推荐
JeffongTan4 小时前
在LWC中镶嵌VF Page获取用户IP
前端·javascript·salesforce
91刘仁德6 小时前
MYSQL 事务原理及使用
android·mysql·adb
陆枫Larry7 小时前
Astro 是什么
前端
一笑的小酒馆7 小时前
AndroidKMP之瀑布流实现
android
RainyJiang8 小时前
AI时代下,Android的边界正在消失
android·openai·ai编程
是立不是利8 小时前
写给设计师的 CSS 博客美学指南
前端·css
Android-Flutter8 小时前
android 内存抖动详解
android
默_笙9 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师9 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端
kyriewen9 小时前
我手写了个极简版 React Router——才搞懂 v6 为什么砍了这么多 API
前端·javascript·程序员