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

相关推荐
冰万森4 分钟前
解决 React 项目初始化(npx create-react-app)速度慢的 7 个实用方案
前端·react.js·前端框架
牧羊人_myr17 分钟前
Ajax 技术详解
前端
用户20187928316724 分钟前
浅谈Android PID与UID原理
android
浩男孩26 分钟前
🍀封装个 Button 组件,使用 vitest 来测试一下
前端
蓝银草同学30 分钟前
阿里 Iconfont 项目丢失?手把手教你将已引用的 SVG 图标下载到本地
前端·icon
TimeFine30 分钟前
Android AWS KVS WebRTC 通话声道切换到媒体音乐声道
android
布列瑟农的星空40 分钟前
重学React —— React事件机制 vs 浏览器事件机制
前端
一小池勺1 小时前
CommonJS
前端·面试
孙牛牛1 小时前
实战分享:一招解决嵌套依赖版本失控问题,以 undici 为例
前端