Android系统启动过程分析

作者: 慕涵盛华 | 来源:发表于2020-03-26 21:50 被阅读0次

    主要流程

    简化流程图

    init进程启动过程

    init进程是Android系统中用户空间的第一个进程。进程号为1。

    引入init进程

    第一步

    当电源按下时引导芯片代码从预定的地方(固化为ROM中)开始执行。加载引导程序BootLoaderRAM中执行。

    第二步

    BootLoader是在Android操作系统开始运行前的一个小程序,主要作用是把系统OS拉起来运行。

    第三步

    当内核完成系统设置后,在系统文件中寻找init.rc文件,并启动init进程。

    启动init进程就会执行它的入口函数main,文件路径为:system/core/init/init.cpp

    int main(int argc, char** argv) {
        ......
        if (is_first_stage) {
            boot_clock::time_point start_time = boot_clock::now();
            umask(0);
            //创建和挂载启动所需要的文件目录
            mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
            mkdir("/dev/pts", 0755);
            mkdir("/dev/socket", 0755);
            mount("devpts", "/dev/pts", "devpts", 0, NULL);
            #define MAKE_STR(x) __STRING(x)
            mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
            chmod("/proc/cmdline", 0440);
            gid_t groups[] = { AID_READPROC };
            setgroups(arraysize(groups), groups);
            mount("sysfs", "/sys", "sysfs", 0, NULL);
            mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
            mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
            mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
            mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
            ......
        }
        ......
        //对属性服务进行初始化
        property_init();
        ......
    
        epoll_fd = epoll_create1(EPOLL_CLOEXEC);
        if (epoll_fd == -1) {
            PLOG(ERROR) << "epoll_create1 failed";
            exit(1);
        }
        //用于设置子进程信号处理函数,如果子进程异常退出,init进程会调用该函 
        //数中设置的信号处理函数进行处理。
        signal_handler_init();
        ......
        //启动属性服务
        start_property_service();
        ......
        if (bootscript.empty()) {
            //解析init.rc配置文件
            parser.ParseConfig("/init.rc");
            parser.set_is_system_etc_init_loaded(
                    parser.ParseConfig("/system/etc/init"));
            parser.set_is_vendor_etc_init_loaded(
                    parser.ParseConfig("/vendor/etc/init"));
            parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
        } 
        ......
        while (true) {
            ......
            if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
                am.ExecuteOneCommand();
            }
            if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
                //重启死去的服务
                restart_processes();
            }
            ......
        }
        return 0;
    }
    

    从上述代码中可以看出,init进程主要做了三件事:

    • 创建和挂载启动所需的文件目录。

    启动挂载了tmpfs、devpts、proc、sysfs和selinuxfs共5种文件系统,这些是系统运行时目录,也就是说只有在系统运行的时候才会存在。

    • 初始化和启动属性服务。

    属性服务类似Windows平台上的注册表管理器,注册表中以key-value的形式来记录用户、软件的一些使用信息。即使系统或软件重启,也能够根据之前注册表中的记录,进行相应的初始化工作。

    • 解析init.rc文件,创建Zygote进程。

    该文件的路径为:system/core/rootdir/init.rc。它是一个非常重要的配置文件,是由Android初始化语言编写的脚本。Android8.0对该文件进行来拆分,每个服务对应一个rc文件,启动Zygote的脚本在init.zygoteXX.rc中定义,代表多少位处理器。这里以64位为例。

    system/core/rootdir/init.zygote64.rc

    service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
        class main
        priority -20
        user root
        group root readproc
        socket zygote stream 660 root system
        onrestart write /sys/android_power/request_state wake
        onrestart write /sys/power/state on
        onrestart restart audioserver
        onrestart restart cameraserver
        onrestart restart media
        onrestart restart netd
        onrestart restart wificond
        writepid /dev/cpuset/foreground/tasks
    

    这里我们只分析zygote进程的创建,所以只贴出了init.rc文件中的Serivice类型的语句,省略了其他语句;这是由Android初始化语言编写的。它的格式如下:
    service <name> <pathname> [ <argument> ]* //名字 执行程序路径 传递参数
    < option > //修饰词,影响什么时候启动,如何启动service。
    < option >
    ......
    上面的代码的含义就是:通知init进程创建名为zygote的进程,这个进程的执行路径为:/system/bin/app/_process64,其后面的代码是传递给app_process64的参数。class main指的是zygoteclassnamemain

    init.rc中的Service类型的语句有相应的类来进行解析,Service语句采用ServiceParser来进行解析,该实现代码在system/core/init/service.app中,代码在这不再贴出,大概的解析过程就是:根据参数创建出Service对象,然后根据选项域中的内容填充Service对象,最后将该对象加入vector类型的Service链表中。

    init.rc中有如下代码:

    ......
    on nonencrypted
        class_start main
        class_start late_start
    ......
    

    class_start是Android初始化语言中的Command类型的语句,对应的函数为do_class_start含义就是启动classname为main的Service。,从上述代码我们知道zygoteclassnamemain。

    do_class_start函数是在system/core/bin/builtins.cpp中,代码如下:

    static int do_class_start(const std::vector<std::string>& args) {
        ServiceManager::GetInstance().
            ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
        return 0;
    }
    

    ForEachServiceInClass函数会遍历Service链表,找到classnamemainZygote,并执行StartIfNotDisabled ()函数。

    StartIfNotDisabled ()函数的代码是在system/core/init/service.cpp中定义的,代码如下:

    bool Service::StartIfNotDisabled() {
        if (!(flags_ & SVC_DISABLED)) {
            return Start();
        } else {
            flags_ |= SVC_DISABLED_START;
        }
        return true;
    }
    

    如果Service没有在其对应的rc文件中设置disabled选项,就会执行Start()函数,Zygote对应的文件没有设置disabled选项

    Start()函数:system/core/init/service.cpp

    bool Service::Start() { 
        flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
        //如果已运行,直接返回
        if (flags_ & SVC_RUNNING) {
            return false;
        }
        ......
        struct stat sb;
        //判断需要启动的Service对应的执行文件是否存在,存在才会执行。
        if (stat(args_[0].c_str(), &sb) == -1) {
            PLOG(ERROR) << "cannot find '" << args_[0] << "', disabling '" << name_ << "'";
            flags_ |= SVC_DISABLED;
            return false;
        }
        ......
        pid_t pid = -1;
        if (namespace_flags_) {
            pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
        } else {
            //如果没有启动,调用fork函数创建子进程
            pid = fork();
        }
    
        if (pid == 0) {
            umask(077);
            ......
            //调用execve函数,子进程就会被启动
            if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
                PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
            }
            _exit(127);
        }
        ......
        return true;
    }
    

    调用execve 函数,子进程就会被启动,就是执行对应的main函数Zygote的执行路径为:system/bin/app_process64,对应的文件为app_main.cpp

    frameworks/base/cmds/app_process/app_main.cpp

    int main(int argc, char* const argv[])
    {
        ......
        while (i < argc) {
            const char* arg = argv[i++];
            if (strcmp(arg, "--zygote") == 0) {
                zygote = true;
                niceName = ZYGOTE_NICE_NAME;
            } else if (strcmp(arg, "--start-system-server") == 0) {
                startSystemServer = true;
            } else if (strcmp(arg, "--application") == 0) {
                application = true;
            } else if (strncmp(arg, "--nice-name=", 12) == 0) {
                niceName.setTo(arg + 12);
            } else if (strncmp(arg, "--", 2) != 0) {
                className.setTo(arg);
                break;
            } else {
                --i;
                break;
            }
        }
        ......
        if (zygote) {
            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
        } else if (className) {
            runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
        } else {
            fprintf(stderr, "Error: no class name or --zygote supplied.\n");
            app_usage();
            LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        }
    }
    

    调用runtime.start函数就启动了Zygote进程

    Zygote进程

    Android系统中,DVM和ART、应用程序进程以及运行系统的关键服务SystemServer进程都是有Zygote进程创建的,我们也称它为孵化器。它通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动的时候会创建DVM或者ART,因此通过fock而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM或者ART的实例副本(也就是说一个Android应用程序对应这一个DVM或者ART)。

    Zygote进程都是通过fock自身来创建子进程的,这样Zygote进程以及子进程都会进入app_main.cppmain函数,所以在上述代码中先区分来当前运行在哪个进程中。运行Zygote进程就会执行AndroidRuntime.start函数

    frameworks/base/core/jni/AndroidRuntime.cpp代码如下:

    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
    {
        ......
        JniInvocation jni_invocation;
        jni_invocation.Init(NULL);
        JNIEnv* env;
        //启动Java虚拟机
        if (startVm(&mJavaVM, &env, zygote) != 0) {
            return;
        }
        onVmCreated(env);
        //为JVM注册JNI方法
        if (startReg(env) < 0) {
            ALOGE("Unable to register all android natives\n");
            return;
        }
        ......
        //从app_main传过来的参数classname值为:“com.android.internal.os.ZygoteInit”
        classNameStr = env->NewStringUTF(className);
        assert(classNameStr != NULL);
        env->SetObjectArrayElement(strArray, 0, classNameStr);
    
        for (size_t i = 0; i < options.size(); ++i) {
            jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
            assert(optionsStr != NULL);
            env->SetObjectArrayElement(strArray, i + 1, optionsStr);
        }
        //将classname的“.”替换成“/”
        char* slashClassName = toSlashClassName(className);
        //找到ZygoteInit
        jclass startClass = env->FindClass(slashClassName);
        if (startClass == NULL) {
            ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        } else {
            //找到ZygoteInit的main函数
            jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
                "([Ljava/lang/String;)V");
            if (startMeth == NULL) {
                ALOGE("JavaVM unable to find main() in '%s'\n", className);
            } else {
                //通过JNI调用ZygoteInit的main函数
                env->CallStaticVoidMethod(startClass, startMeth, strArray);
    
    #if 0
                if (env->ExceptionCheck())
                    threadExitUncaughtException(env);
    #endif
            }
        }
        ......
    }
    

    上述代码最后会调用ZygoteInitmain方法,该方法是由Java语言编写的,当前的运行逻辑在Native中,这就需要通过JNI来调用Java。这样Zygote就从Native层近入了Java框架层

    /frameworks/base/core/java/com/android/internal/os/ZygoteInit.javamain方法代码如下:

    public static void main(String argv[]) {
        ......
        try {
            ......
            //创建一个Server端的socket,socketName = “zygote”
           //在这个socket上会等待AMS的请求
            zygoteServer.registerServerSocket(socketName);
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                //预加载类和资源
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }
            //启动SystemServer进程
            if (startSystemServer) {
                startSystemServer(abiList, socketName, zygoteServer);
            }
            //等待AMS请求,里面是一个while(true)循环
            zygoteServer.runSelectLoop(abiList);
            zygoteServer.closeServerSocket();
        }......
    }
    

    该方法中主要做了4件事:
    1.创建一个Server端的socket(LocalServerSocket)。
    2.预加载类和资源。
    3.启动SystemServer进程。
    4.等待AMS请求创建新的应用程序进程。

    从上面的代码我们看出Zygote进程主要做了如下几件事情:

    • 1.创建Java虚拟机并为Java虚拟机注册JNI方法。
    • 2.通过JNI调用ZygoteInitmain函数进入Zygote的Java框架层。
    • 3.通过registerServerSocket 方法创建服务端Socket,并通过runSelectLoop 方法等待AMS的请求来创建新的应用程序进程。
    • 4.启动SystemServer进程。

    SystemServer进程

    SystemServer进程主要用于创建系统服务,AMS、WMS、PMS都是由它来创建的。从上面得知通过调用ZygoteInitstartSystemServer 方法来启动SystemServer进程,下面就看一下该方法的代码:

    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        ......
        //创建args数组,该数组用来保存启动SystemServer的启动参数
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;
        int pid;
        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
            //创建一个子进程,也就是SystemServer进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
        //当前代码运行在子进程中,也就是SystemServer进程
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            //SystemServer进程复制了Zygote进程的地址空间,因此也会得到Zygote创建的Socket。
            //该Socket对SystemServer进程没有用,所以要关闭。
            zygoteServer.closeServerSocket();
            //处理SystemServer进程
            handleSystemServerProcess(parsedArgs);
        }
    
        return true;
    }
    

    从上面代码可以看出,SystemServer进程的用户id和用户组id被设置为1000,并且拥有1001~1010、1018、1021、1032、3001~3010的权限;进程名字为system_server;启动的类名为:com.android.server.SystemServer

    创建出SystemServer进程之后就会在该进程调用ZygoteInit.handleSystemServerProcess 方法,下面看一下该方法的代码:

    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {
        ......
        if (parsedArgs.invokeWith != null) {
          ......
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                //创建PathClassLoader
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
                Thread.currentThread().setContextClassLoader(cl);
            }
            //调用zygoteInit方法
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }
    
    public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();
        RuntimeInit.commonInit();
        //启动Binder线程池
        ZygoteInit.nativeZygoteInit();
        //执行SystemServer的main方法
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
    

    zygoteInit方法中创建了Binder线程池,这样SystemServer进程就可以使用Binder于其他进程进行通信了。

    创建Binder线程池后会调用RuntimeInit.applicationInit方法,下面就接着看下该方法的代码:
    /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        ......
        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }
    
    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        Class<?> cl;
        try {
            //通过反射得到SystemServer类
            cl = Class.forName(className, true, classLoader);
        }......
        Method m;
        try {
            //找到SystemServer的main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        }......
        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }
        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }
    

    通过反射得到SystemServer,className的值就是上面提到的com.android.server.SystemServer,然后再找到main方法,最后将main方法传入Zygote .MethodAndArgsCaller异常中并抛出该异常。捕获该异常的代码在ZygoteInit.main方法中,该main方法会调用SystemServermain方法

    那为什么不直接在invokeStaticMain方法中调用呢?而是在异常捕获中调用?

    原因是异常处理会清楚所有设置过程中需要的堆栈帧,让SystemServermain方法看起来像是SystemServer进程的入口。(在Zygote
    启动SystemServer进程之后,SystemServer进程做了很多准备工作,这些工作都是在main方法调用之前做的。)

    /frameworks/base/core/java/com/android/internal/os/ZygoteInit.javamain方法代码:

    public static void main(String argv[]) {
        ......
        try {
        ......
        //捕获MethodAndArgsCaller异常
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }
    

    在异常处理中直接调用Zygote.MethodAndArgsCallerrun方法,可以看出MethodAndArgsCallerZygote的静态内部类。

    /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        ......
        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }
        ......
        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            }......
        }
    }
    

    此处的mMethod就是SystemServermain方法

    这样就进入了SystemServermain方法

    /frameworks/base/services/java/com/android/server/SystemServer.java

    public static void main(String[] args) {
        new SystemServer().run();
    }
    
    private void run() {
        try {
            ......
            //创建Looper
            Looper.prepareMainLooper();
            //加载动态库“libandroid_servers.so”
            System.loadLibrary("android_servers");
            performPendingShutdown();
            //创建系统的上下文Context
            createSystemContext();
            // 创建SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }
        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            //启动引导服务
            startBootstrapServices();
            //启动核心服务
            startCoreServices();
            //启动其他服务
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        }......
    }
    

    通过上面可以看出系统服务分为三种:
    1.引导服务。
    2.核心服务。
    3.其他服务。

    private void startBootstrapServices() {
        ......
        Installer installer = mSystemServiceManager.startService(Installer.class);
        ......
        mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
        ......
       //需要注意的是 ActivityManagerService.Lifecycle实现了SystemService
        mActivityManagerService = mSystemServiceManager.startService(
                    ActivityManagerService.Lifecycle.class).getService();
        ......
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        ......
        //在该方法中会把ActivityManagerService添加到ServiceManager中
        mActivityManagerService.setSystemProcess();
        ......
    }
    private void startCoreServices() {
        ......
        mSystemServiceManager.startService(DropBoxManagerService.class);
        traceEnd();
        ......
        mSystemServiceManager.startService(BatteryService.class);
        ......
    }
    private void startOtherServices() {
        ......
        mSystemServiceManager.startService(KeyChainSystemService.class);
        ......
        mSystemServiceManager.startService(TelecomLoaderService.class);
        ......
    }
    

    部分服务表:

    引导服务 作用
    Installer 系统安装APK时的一个服务,启动完成Installer服务之后才能启动其他的服务
    ActivityManagerService 负责四大组件的启动、切换和调度
    PowerManagerService 计算系统中和Power相关的计算,然后决策系统应该如何反应
    LightsService 管理和显示背光LED
    DisplayManagerService 用来管理所有显示的设备
    UserManagerService 多用户模式管理
    SensorService 为系统提供各种感应器服务
    PackageManagerService 用来对APK进行安、解析、删除、卸载等操作
    ...... .....
    核心服务
    DropBoxManagerService 用于生成和管理系统运行时的一些日志文件
    BatteryService 管理电池相关的服务
    UsageStatsService 收集用户使用每一个app的频率、使用时长
    WebViewUpdateService WebView更新服务
    其他服务
    CameraService 摄像头相关服务
    AlarmManagerService 全局定时器管理服务
    InputManagerService 管理输入事件
    WindowManagerService 窗口管理服务
    VrManagerService VR模式管理服务
    BluetoothService 蓝牙管理服务
    NotificationManagerService 通知管理服务
    DeviceStorageMonitorService 存储相关管理服务
    LocationManagerService 定位管理服务
    AudioService 音频相关管理服务
    ...... ......

    我们从上面看出相关的服务一种是通过SystemServiceManagerstartService方法来启动的;另一种是直接调用服务的main方法,比如:PackageManagerService。下面分别看一下这两种方式的代码实现:

    /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

    public class SystemServiceManager {
        ......
        private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
        ......
        //startService方法有几个重载,最终都会调用该方法
        public void startService(@NonNull final SystemService service) {
            //注册服务
            mServices.add(service);
            // Start it.
            long time = System.currentTimeMillis();
            try {
                //调用服务自身的onStart方法
                service.onStart();
            }......
        }
    }
    public abstract class SystemService {
        ......
    }
    

    先将服务添加到mService中,它是一个存储SystemService类型的ArrayList,这样就完成来该服务的注册工作。然后调用服务自身的onStart()方法来启动服务。由SystemServiceManager创建并启动的服务,都是继承了SystemService,但是并没有实现IBinder,所以是不可以进行Binder通信的,也就是由它管理的服务是用于进程内部通信的。

    /frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

    public class PackageManagerService extends IPackageManager.Stub
            implements PackageSender {
        ......
        public static PackageManagerService main(Context context, Installer installer,
                boolean factoryTest, boolean onlyCore) {
            PackageManagerServiceCompilerMapping.checkProperties();
            PackageManagerService m = new PackageManagerService(context, installer,
                    factoryTest, onlyCore);
            m.enableSystemUserPackages();
            //注册
            ServiceManager.addService("package", m);
            return m;
        }
        ......
    }
    

    创建对象后添加到ServiceManager中,它是用来管理系统中各种Service的,由它管理的服务都实现了IBinder,所以在ServiceManager中注册的服务是用于进程间通信的:用于系统C/S架构中的Binder通信机制。客户端要使用某个Service,需要先到ServiceManager中查询Service的信息,然后根据该信息与Service所在的Server进程建立通信,这样客户端就可以使用Service了。

    从上面的代码我们看出SystemServer进程主要做了如下几件事情:

    • 1.启动Binder线程池,这样就可以与其他进程进行通信了。
    • 2.创建SystemServiceManager,用于对系统其他服务进行创建、启动和声明周期管理。
    • 3.启动各种系统服务。

    SystemServer进程Zygote进程fork的第一个进程。其中WindowManagerService、ActivityManagerService、PackageManagerService等重要的可以binder通信的服务都运行在这个SystemServer进程

    Launcher启动过程

    系统启动的最后一步就是启动一个应用程序来显示系统中已经安装的应用程序,这个程序就叫做Launcher。它在启动过程中会请求PackagerMangerService返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上。这样用户就可以通过点击快捷图标来启动相应的应用程序了。

    在上面SystemServer进程分析过程中,我们知道ActivityManagerService(简称:AMS)是负责四大组件的启动、切换和调度的。系统桌面本身也是一个Activity,所以Launcher的启动是在AMS中进行的,启动Launcher的入口是AMSsystemReady方法。该方法是在SystemServerstartOtherServices方法中被调用的,下面就看一下该方法的实现代码:

    private void startOtherServices(){
        ......
        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();
        ......
    }
    

    /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
        ......
        synchronized (this) {
            ......
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
            ......
        }
    }
    

    该方法中调用了ActivityStackSupervisorresumeFocusedStackTopActivityLocked()方法

    /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        ......
        return false;
    }
    

    ActivityStack是用来描述Activity堆栈的。

    最后经过重重调用,最终会调用AMSstartHomeActivityLocked方法

    boolean startHomeActivityLocked(int userId, String reason) {
        //判断系统的运行模式和mTopAction的值
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {
            return false;
        }
        获取Luncher启动所需要的Intent
        Intent intent = getHomeIntent();
        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
        if (aInfo != null) {
            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
            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);
                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
                //启动Luncher
                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
            }
        } else {
            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
        }
        return true;
    }
    
    Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }
    

    mFactoryTest代表系统运行模式,运行模式有三种:非工厂模式、低级工厂模式和高级工厂模式mTopAction表示第一个被启动Activity组件的Action,它的默认值为:Intent.ACTION_MAIN

    getHomeIntent方法中,如果mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL(低级工厂模式)Category的值为:Intent.CATEGORY_HOME。也就是说如果系统运行模式不是低级工厂模式那么:
    action = Intent.ACTION_MAIN
    category = Intent.CATEGORY_HOME
    而服务这个描述的应用程序就是Luncher,因为LuncherAndroidManifest文件中的intent-filter匹配了这两个值:

    /packages/apps/Launcher3/AndroidManifest.xml

    <manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.launcher3">
    <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
    ......
    <application
        ......
        <activity
            android:name="com.android.launcher3.Launcher"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="unspecified"
            android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
            android:resizeableActivity="true"
            android:resumeWhilePausing="true"
            android:taskAffinity=""
            android:enabled="true">
            <intent-filter>
                //匹配规则
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY"/>
                <category android:name="android.intent.category.LAUNCHER_APP" />
            </intent-filter>
        </activity>
        ......
    </application>
    </manifest>
    

    Luncher完成启动后,作为桌面它会显示应用程序图标。

    参考《Android进阶解密》

    实战

    相关文章

      网友评论

        本文标题:Android系统启动过程分析

        本文链接:https://www.haomeiwen.com/subject/givhuhtx.html