Android系统启动流程(nougat7.1.1_r6)


一.Android启动简介

Android 是一种基于 Linux 的开放源代码软件栈,为广泛的设备和机型而创建。下图所示为 Android 平台的主要组件。
Android系统启动流程(nougat7.1.1_r6)_第1张图片

Linux 内核

Android 平台的基础是 Linux 内核。例如,Android Runtime (ART) 依靠 Linux 内核来执行底层功能,例如线程和低层内存管理。

  • 音频驱动(Audio):常用的基于ALSA的高级Linux声音体系驱动。
  • Binder IPC驱动:Android的一个特殊的驱动程序,具有单独的设备节点,提供进程间通信的功能。
  • 显示驱动(Display):基于Linux的帧缓冲(Frame Buffer)驱动。
  • 键盘驱动(KeyBoard):作为输入设备的键盘驱动。
  • 蓝牙驱动(Bluetooth Driver):基于IEEE 802.15.1标准的无线传输技术。
  • 照相机驱动(Camera Driver):常用的基于Linux的v412(Video for Linux)的驱动。
  • Flash内存驱动(Flase Memory Driver):基于MTD的Flash驱动程序。
  • WiFi驱动:基于IEEE 802.11标准的驱动程序。

HAL(Hardware Abstraction Layer)

硬件抽象层 (HAL) 提供标准界面,向更高级别的 Java API 框架显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如相机或蓝牙模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。

硬件抽象层 (HAL) 会定义一个标准接口以供硬件供应商实现,并允许 Android 忽略较低别的驱动程序实现。借助 HAL,可以顺利实现相关功能,而不会影响或无需更改更高级别的系统。HAL 实现会被封装成模块 (.so) 文件,并会由 Android 系统适时地加载。
Android系统启动流程(nougat7.1.1_r6)_第2张图片

标准的HAL结构中,HAL借口包含两个通用的组件:一个模块和一个设备。

  • 模块:表示被封装切存储为共享库(.so file)的实现。里面包含模块版本等元数据。
  • 设备:提取产品的实际硬件。例如,音频模块可能会包含主音频设备、USB 音频设备或蓝牙 A2DP 音频设备。

Android Runtime

Android Runtime时运行在Android 5.0(API 级别 21)或更高版本的设备上。ART 编写为通过执行 DEX 文件在低内存设备上运行多个虚拟机,DEX 文件是一种专为 Android 设计的字节码格式,经过优化,使用的内存很少。编译工具链(例如 Jack)将 Java 源代码编译为 DEX 字节码,使其可在 Android 平台上运行。
ART 的部分主要功能包括:

  • 预先 (AOT) 和即时 (JIT) 编译
  • 优化的垃圾回收 (GC)
  • 更好的调试支持,包括专用采样分析器、详细的诊断异常和崩溃报告,并且能够设置监视点以监控特定字段

原生 C/C++ 库 :

许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能。

  • OpenGl ES: Android包括支持高性能2 d和3 d图形与开放图形库。OpenGL是一个跨平台的图形API,它为3D图形处理硬件指定了一个标准的软件接口。
  • WebKit:一个开源的浏览器引擎.
  • OenMAX AL:一个多媒体应用程序的标准,基于 Khronos Group OpenMAX AL™ 1.0.1 standard,在Android4.0以上使用。
  • Libc:从BSD继承来的标准C系统函数库,专门为基于embedded linux的设备定制。

Application Framework(应用框架层)

  • View System:可用以构建应用的 UI,包括列表、网格、文本框、按钮甚至可嵌入的网络浏览器
  • Content Providers:它可以让一个应用访问另一个应用的数据,或共享它们自己的数据。
  • Resource Manager:用于访问非代码资源,例如本地化的字符串、图形和布局文件 。
  • Notification Manager:可让所有应用在状态栏中显示自定义提醒 。
  • Activity Manager:用于管理应用的生命周期,提供常见的导航返回栈
  • Window Manager:管理所有的窗口程序。
  • Package Manager:Android系统内包的程序管理。

System Apps

Android 随附一套用于电子邮件、短信、日历、互联网浏览和联系人等的核心应用。平台随附的应用与用户可以选择安装的应用一样,没有特殊状态。因此第三方应用可成为用户的默认网络浏览器、短信 Messenger 甚至默认键盘(有一些例外,例如系统的“设置”应用)。


其实分析了这张图都有什么东西,但是对于安卓系统启动流程还是很模糊的。我不打算循序渐进,先放一张图,来对我这篇文章中提到的安卓系统流程有个整体的了解。
Android系统启动流程(nougat7.1.1_r6)_第3张图片

二、Linux内核启动

开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机。

1.引导程序Bootloader

BootLoader是在操作系统运行之前运行的一段程序,它可以将系统的软硬件环境带到一个合适状态,为运行操作系统做好准备。它比较像电脑上的BIOS,它就是要把OS拉起来运行。Bootloader有三种模式如下:
a:开机后按组合键启动到fastboot模式,即命令或SD卡烧写模式,不加载内核及文件系统,可以通过数据线与电脑连接,然后在电脑上执行一些命令,如刷系统镜像到手机上。
b:开机后按组合键启动到recovery模式,加载recovery.img,recovery.img包含内核,部分文件系统,可以读sdcard中的update.zip进行刷机,也可以清除cache和用户数据。
c:开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机。
正常启动流程,也就是c流程。
Bootloader做的事情主要有:初始化CPU时钟,内存,串口等;设置linux启动参数;加载Linux各种各样的内核镜像到SDRAM中。

2.linux内核启动

内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动root进程或者系统的第一个进程。

三、Init进程

Init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程.

1.Init入口函数

system/core/init/init.cpp

init的入口函数为main。

int main(int argc, char** argv) {
   ...
       // Get the basic filesystem setup we need put together in the initramdisk on / and then we'll let the rc file figure out the rest.

    //基本的系统的设置。挂载信息,创建一些文件夹。从注释中我们可以看到,它把一些其他的操作放到了rc文件下。之后会提到。
    if (is_first_stage) {
        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));
        mount("sysfs", "/sys", "sysfs", 0, NULL);
    } 
    //重定向标准输入\输出到 dev/_null_
    open_devnull_stdio();
    //初始化内核log系统
    klog_init();
    klog_set_level(KLOG_NOTICE_LEVEL);

    NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
    if (!is_first_stage) {
        close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
       //初始化属性相关资源,利用ashmem共享。
        property_init();

        process_kernel_dt();
        process_kernel_cmdline();

        export_kernel_boot_props();
    }

    // Set up SELinux, including loading the SELinux policy if we're in the kernel domain.
    //设置SELinux policy策略。
    selinux_initialize(is_first_stage);
    if (is_first_stage) {
        if (restorecon("/init") == -1) {
            ERROR("restorecon failed: %s\n", strerror(errno));
            security_failure();
        }
        char* path = argv[0];
        char* args[] = { path, const_cast<char*>("--second-stage"), nullptr };
        if (execv(path, args) == -1) {
            ERROR("execv(\"%s\") failed: %s\n", path, strerror(errno));
            security_failure();
        }
    }

    NOTICE("Running restorecon...\n");
    restorecon("/dev");
    restorecon("/dev/socket");
    restorecon("/dev/__properties__");
    restorecon("/property_contexts");
    restorecon_recursive("/sys");

    //创建epoll句柄
    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
    if (epoll_fd == -1) {
        ERROR("epoll_create1 failed: %s\n", strerror(errno));
        exit(1);
    }

    signal_handler_init();
    property_load_boot_defaults();
    export_oem_lock_status();
    //启动属性服务
    start_property_service();
 const BuiltinFunctionMap function_map;
    Action::set_function_map(&function_map);
    Parser& parser = Parser::GetInstance();
    parser.AddSectionParser("service",std::make_unique());
    parser.AddSectionParser("on", std::make_unique());
    parser.AddSectionParser("import", std::make_unique());
    //解析init.rc。
    parser.ParseConfig("/init.rc");
    //解析完成配置文件之后,会得到一系列的action动作。init和boot。
    ActionManager& am = ActionManager::GetInstance();
     am.QueueEventTrigger("early-init");
    // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
    am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    // ... so that we can start queuing up actions that require stuff from /dev.
    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
    am.QueueBuiltinAction(keychord_init_action, "keychord_init");
    am.QueueBuiltinAction(console_init_action, "console_init");

    // Trigger all the boot actions to get us started.
    am.QueueEventTrigger("init");

    // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
    // wasn't ready immediately after wait_for_coldboot_done
    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");

    // Don't mount filesystems or start core system services in charger mode.
    std::string bootmode = property_get("ro.bootmode");
    if (bootmode == "charger") {
        am.QueueEventTrigger("charger");
    } else {
        am.QueueEventTrigger("late-init");
    }

    // Run all property triggers based on current state of the properties.
    am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");

    while (true) {
    //while循环不断调用ExecuteOneCommand函数时,匹配的action。
        if (!waiting_for_exec) {
            am.ExecuteOneCommand();
            restart_processes();
        }

        int timeout = -1;
        if (process_needs_restart) {
            timeout = (process_needs_restart - gettime()) * 1000;
            if (timeout < 0)
                timeout = 0;
        }

        if (am.HasMoreCommands()) {
            timeout = 0;
        }

        bootchart_sample(&timeout);

        epoll_event ev;
        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
        if (nr == -1) {
            ERROR("epoll_wait failed: %s\n", strerror(errno));
        } else if (nr == 1) {
        //通过epoll来监听,处理属性服务相关的事情。
            ((void (*)()) ev.data.ptr)();
        }
    }

    return 0;
}

我们对上面的代码进行总结:
1.创建文件系统目录并挂载相关的文件系统。
2.初始化内核log系统。
3.初始化属性相关资源,利用ashmem共享。
4.设置SELinux policy策略

  • Android 使用 SELinux 对所有进程强制执行强制访问控制 (MAC),其中包括以 Root/超级用户权限运行的进程(也称为 Linux 功能)。SELinux 能够限制特权进程并能够自动创建安全政策,从而可提升 Android 的安全性。
  • 关于SELinux 中有详细的介绍。(https://source.android.com/security/selinux/)。需要。

5.创建epoll句柄。

  • epoll仅仅是一个异步事件的通知机制,其本身并不作任何的IO读写操作,它只负责告诉你是不是可以读或可以写了,而具体的读写操作,还要应用程序自己来完成。
  • 该函数生成一个epoll专用的文件描述符。它其实是在内核申请一空间,用来存放你想关注的fd上是否发生的事件。size就是你在这个epoll fd上能关注的最大fd数,这个参数不同于select()中的第一个参数,给出最大监听的fd+1的值。需要注意的是,当创建好epoll句柄后,它就会占用一个fd值,在Linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。

6.启动属性服务。

//system/core/init/property_service.cpp
void start_property_service() {
    property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
                                    0666, 0, 0, NULL);
    if (property_set_fd == -1) {
        ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
        exit(1);
    }

    listen(property_set_fd, 8);

    register_epoll_handler(property_set_fd, handle_property_set_fd);
}
  • 创建了socket套接字,然后监听,并且调用register_epoll_handler函数把socket的fd放入了epoll中。

7.通过parser拆分,解析init.rc。
8.while循环,通过epoll句柄来处理属性服务相关的事情。

在上面中解析init.rc是我们比较关注的事情。

2.Init控制Service

init.rc是什么?
我们在android源码的README.md中可以读到详细的用法。

  • Android Init Language

在这里面我做一下简要介绍:

init.rc是一个配置文件,内部由Android初始化语言编写(Android Init Language)编写的脚本,Android Init语言包含五个宽泛的语句类型:操作(actions)、命令(commands)、服务(services)、选项(options)和导入(imports)。

AIL在编写时需要分成多个部分(Section),而每一部分的开头需要指定Actions或Services。也就是说,每一个Actions或Services确定一个Section。而所有的Commands和Options只能属于最近定义的Section。如果Commands和Options在第一个Section之前被定义,它们将被忽略。

init的main函数中我们看到,通过parser拆分,解析init.rc。

从init.rc(路径:sysetm/core/rootdir/init.rc)中我们可以看到:

import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc

import用来初始化一些配置文件的。我们可以看到配置了zygote。
zygote的.rc文件有多个。主要就是来区分不同的平台(32、64及64_32)。
init.rc文件进行了拆分了每个服务一个rc文件。我们以nit.zygote64.rc为例。

其中service用于通知init进程创建名zygote的进程,

//system/core/rootdir/init.zygote64.rc

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    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
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

services的语法规则是这样的:

service   [  ]* 
//<名字><执行程序路径><参数>
   

其中:name 是程序的名字,pathname是执行程序路径,argument参数。option 是什么时候如何启动service。
我们可以看到 启动zygote的 class 名字 是main。

3. init启动zygote

我们在init.rc文件中找找关于main的代码。

//system/core/rootdir/init.rc

...
on nonencrypted    
    # A/B update verifier that marks a successful boot.  
    exec - root -- /system/bin/update_verifier nonencrypted  
    class_start main         
    class_start late_start 
...

其中class_start是一个COMMAND,对应的函数为do_class_start。main指的就是zygote,因此class_start main用来启动zygote。do_class_start函数在builtins.cpp中定义,如下所示。

//system/core/init/builtins.cpp
static int do_class_start(const std::vector<std::string>& args) {
        /* Starting a class does not start services
         * which are explicitly disabled.  They must
         * be started individually.
         */
     //ServiceManager在system\core\init\service.cpp目录中定义
     //serviceManager::GetInstance().ForEachServiceInClass()方法。
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
    return 0;
}

这段代码中调用了ServiceManager的单例模式,ForEachServiceInClass循环遍历service。

//system\core\init\service.cpp
bool Service::StartIfNotDisabled() {
    if (!(flags_ & SVC_DISABLED)) {
        return Start();
    } else {
        flags_ |= SVC_DISABLED_START;
    }
    return true;
}

StartIfNotDisabled从字面意思就可以看出来如果不是启动失败的就开始,所以我们接着查看Start方法

//system\core\init\service.cpp
bool Service::Start() {
    flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
    time_started_ = 0;
    if (flags_ & SVC_RUNNING) {//如果Service已经运行,则不启动
        return false;
    }
    bool needs_console = (flags_ & SVC_CONSOLE);
    if (needs_console && !have_console) {
        ERROR("service '%s' requires console\n", name_.c_str());
        flags_ |= SVC_DISABLED;
        return false;
    }
  //判断需要启动的Service的对应的执行文件是否存在,不存在则不启动该Service
    struct stat sb;
    if (stat(args_[0].c_str(), &sb) == -1) {
        ERROR("cannot find '%s' (%s), disabling '%s'\n",
              args_[0].c_str(), strerror(errno), name_.c_str());
        flags_ |= SVC_DISABLED;
        return false;
    }

...
//fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值
    //(1)在子进程中,fork返回0;
    //(2)在父进程中,fork返回新创建子进程的进程ID;
    //(3)如果出现错误,fork返回一个负值;

//1.fork函数创建子进程
  pid_t pid = fork();
    if (pid == 0) {//运行在子进程中
        umask(077);
        for (const auto& ei : envvars_) {
            add_environment(ei.name.c_str(), ei.value.c_str());
        }

    for (const auto& si : sockets_) {
                int socket_type = ((si.type == "stream" ? SOCK_STREAM :
                                    (si.type == "dgram" ? SOCK_DGRAM :
                                     SOCK_SEQPACKET)));
                const char* socketcon =
                    !si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str();

                int s = create_socket(si.name.c_str(), socket_type, si.perm,
                                      si.uid, si.gid, socketcon);
                if (s >= 0) {
                    PublishSocket(si.name, s);
                }
            }
    ...
            //2.execve(执行文件)在父进程中fork一个子进程,在子进程中调用exec函数启动新的程序。
            if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {
                ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
            }

            _exit(127);
        }
    ...
        return true;
    }

从上面的代码中我们可以看出,init.rc运用Android初始化语言,启动了一个servicemanager来管理。然后servicemanager中通过遍历来查找我们要的那个service。其中service.cpp是用来启动的,如果这个service没有,我们fork一个出来。顺便提一句,fork函数在android中有两次运用。一个是主要用来为应用和SystemService fork进程的。一个是java编写的zygote接口,负责为应用和service调用C/C++ zygote的接口执行fork,从而创建VM进程。

通过注释1和2的代码,我们需要找到子进程(system/bin/app_process)到底做了什么,framework/cmds/app_process/app_main.cpp的main函数。

//frameworks/base/cmds/app_process/app_main.cpp

{
    ...
    if (zygote) {
    //1
        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.");
        return 10;
    }
}

注释1处的代码 调用runtime(AppRuntime)的start来启动zygote。也就是说,在主函数中,初始化了运行时环境,并且建立虚拟机,然后运行再com.android.internal.os.ZygoteInit的main函数。

4、Zygote进程

在Android系统中,JavaVM(Java虚拟机)、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建JavaVM,因此通过fock而创建的应用程序进程和SystemServer进程可以在内部获取一个JavaVM的实例拷贝。
Servicemanager和zygote进程就奠定了Android的基础。Zygote这个进程起来才会建立起真正的Android运行空间,初始化建立的Service都是Navtive service。

建立Zygote的主要流程

1.创建AppRuntime并调用其start方法,启动Zygote进程。
2.创建JavaVM并为JavaVM注册JNI.
3.通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
4.通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求。
5.启动SystemServer进程。
Android系统启动流程(nougat7.1.1_r6)_第4张图片

zygote主要的调用函数

1、APPRuntime分析

init启动zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start来启动zygote进程的,我们就从app_main.cpp的main函数开始分析。
frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
    ...
    //AppRuntime继承自AndroidRuntime。稍后对AndroidRuntime进行分析。
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;

    // Everything up to '--' or first non '-' arg goes to the vm.
    //
    // The first argument after the VM args is the "parent dir", which
    // is currently unused.
    //
    // After the parent dir, we expect one or more the following internal
    // arguments :
    //
    // --zygote : Start in zygote mode
    // --start-system-server : Start the system server.
    // --application : Start in application (stand alone, non zygote) mode.
    // --nice-name : The nice name for this process.
    //
    // For non zygote starts, these arguments will be followed by
    // the main class name. All remaining arguments are passed to
    // the main method of this class.
    //
    // For zygote starts, all remaining arguments are passed to the zygote.
    // main function.
    //
    // Note that we must copy argument string values since we will rewrite the
    // entire argument block when we apply the nice name to argv0.


    int i;
    for (i = 0; i < argc; i++) {
        if (argv[i][0] != '-') {
            break;
        }
        if (argv[i][1] == '-' && argv[i][2] == 0) {
            ++i; // Skip --.
            break;
        }
        runtime.addOption(strdup(argv[i]));
    }

    // Parse runtime arguments.  Stop at first unrecognized option.
    //解析参数。如果不识别就停止。
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    //不断循环来解析输入的参数。
    while (i < argc) {
        const char* arg = argv[i++];
        //这些事我们在init.rc中见过的一些参数。
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            //对于64位系统nice_name为zygote64; 32位系统为zygote
            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;
        }
    }

    Vector args;
    if (!className.isEmpty()) {
        // We're not in zygote mode, the only argument we need to pass
        // to RuntimeInit is the application argument.
        //
        // The Remainder of args get passed to startup class main(). Make
        // copies of them before we overwrite them with the process name.
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);
    } else {
        // We're in zygote mode.
        //创建Dalvik虚拟机的目录。/data/dalvik-cache路径
        maybeCreateDalvikCache();

        if (startSystemServer) {
        //加入参数。
            args.add(String8("start-system-server"));
        }

        char prop[PROP_VALUE_MAX];
        if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
            LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                ABI_LIST_PROPERTY);
            return 11;
        }

        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);

        // In zygote mode, pass all remaining arguments to the zygote
        // main() method.
        //剩下的所有都在zygote的main函数中创建。先把这些参数加入args(也就是zygote)中。
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }

    if (!niceName.isEmpty()) {
    //替换进程的名字。zygote终于有名字了。
        runtime.setArgv0(niceName.string());
        set_process_name(niceName.string());
    }

    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.");
        //没有指定类名或zygote,参数错误
        return 10;
    }
}

从上一段中我们看到,通过向runtime.start传入参数来创建ZygoteInit和RuntimeInit。runtime指的就是AppRuntime,AppRuntime声明也在app_main.cpp中,它继承AndroidRuntime,也就是我们调用start其实是调用AndroidRuntime的start函数:

//frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ...
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //创建虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);
    //jni方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    //创建数组
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    //从app_main的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);
    }
    //方法中. 换成/也就是将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit" 
    char* slashClassName = toSlashClassName(className);
    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
        }
    }
  ...
}

2、Zygote的Java框架层

通过JNI调用ZygoteInit的main函数后,Zygote便进入了Java框架层,此前没有任何代码进入过Java框架层,换句换说Zygote开创了Java框架层。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
       ...
        try {
         ...       
            //注册Zygote用的Socket
            registerZygoteSocket(socketName);//1
           ...
           //预加载类和资源
           preload();//2
           SamplingProfilerIntegration.writeZygoteSnapshot();
           gcAndFinalize(); //GC操作

            if (startSystemServer) {
            //启动SystemServer进程,调用Zygote的native方法 forkSystemServer(); 
                startSystemServer(abiList, socketName);//3
            }
            Log.i(TAG, "Accepting command socket connections");
            //等待客户端请求
            runSelectLoop(abiList);//4
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
        //在异常捕获后调用的方法caller.run()
            caller.run(); 
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

注释1处:通过registerZygoteSocket函数来创建一个Server端的Socket,这个Socket用来等待ActivityManagerService来请求Zygote来创建新的应用程序进程。

    private static void registerZygoteSocket(String socketName) {
        if (sServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);//设置文件描述符

                sServerSocket = new LocalServerSocket(fd); ////创建Socket的本地服务端,也就是服务端的Socket。当Zygote进程将SystemServer进程启动后,就会在这个服务端的Socket上来等待ActivityManagerService请求Zygote进程来创建新的应用程序进程。

            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

注释2处用来预加载类和资源。

 static void preload() {
    ....
    //预加载位于/system/etc/preloaded-classes文件中的类
        preloadClasses();
      //预加载资源,包含drawable和color资源/
      主要是 com.android.internal.R.array.preloaded_drawables和com.android.internal.R.array.preloaded_color_state_lists,在应用程序中以com.android.internal.R.xxx开头的资源,便是此时由Zygote加载到内存的。
        preloadResources();
      //预加载OpenGL
        preloadOpenGL();
      //通过System.loadLibrary()方法,
      //预加载"android","compiler_rt","jnigraphics"3个共享库
        preloadSharedLibraries();
        //预加载  文本连接符资源
        preloadTextResources();
        //仅用于zygote进程,用于内存共享的进程
        WebViewFactory.prepareWebViewInZygote();
        endIcuCachePinning();
        warmUpJcaProviders();
    }

注释3处用来启动SystemServer进程,这样系统的关键服务也会由SystemServer进程启动起来。

 private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_IPC_LOCK,
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_RESOURCE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG
        );
        if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
            capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
        }
     //参数准备
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,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);

         // fork子进程,用于运行system_server
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

       //进入子进程system_server
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
       //完成剩余的工作。关闭socket等。
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

注释4处调用runSelectLoop函数来等待客户端请求。由此得知,ZygoteInit的main函数主要做了4件事,接下来我们对主要的事件一一进行分析。

  private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList fds = new ArrayList();
        ArrayList peers = new ArrayList();
        //sServerSocket就是我们在registerZygoteSocket函数中创建的服务端Socket,调用sServerSocket.getFileDescriptor()用来获得该Socket的fd字段的值并添加到fd列表fds中。接下来无限循环用来等待ActivityManagerService请求Zygote进程创建新的应用程序进程。
        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
             //处理轮询状态,当pollFds有事件到来则往下执行,否则阻塞在这里
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
              //采用I/O多路复用机制(Multiplexing Model),当接收到客户端发出连接请求 或者数据处理请求到来,则往下执行;
            // 否则进入continue,跳出本次循环。

                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                 //即fds[0],代表的是sServerSocket,则意味着有客户端连接请求;
                // 则创建ZygoteConnection对象,并添加到fds。

                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        //处理完则从fds中移除该文件描述符
                        fds.remove(i);
                    }
                }
            }
        }
    }

5、SyetemServer进程

SystemServer进程主要的作用是启动各种系统服务,比如
ActivityManagerService,PackageManagerService,WindowManagerService等服务,我们平时熟知的各种系统性的服务其实都是在SystemServer进程中启动的,而当我们的应用需要使用各种系统服务的时候其实也是通过与SystemServer进程通讯获取各种服务对象的句柄,进而执行相应的操作的。

SyetemServer在启动时做了如下工作: 1.启动Binder线程池,这样就可以与其他进程进行通信。 2.创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理。 3.启动各种系统服务。

1、Zygote启动SystemServer进程

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

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
     ...
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            handleSystemServerProcess(parsedArgs);
        }
        return true;
    }

前面提到在ZygoteInit.java的startSystemServer函数中启动了SyetemServer进程。在startSystemServer函数中调用handleSystemServerProcess来启动SyetemServer进程。

2、SystemServer进程启动过程

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
        closeServerSocket();//1
      ...
        if (parsedArgs.invokeWith != null) {
           ...
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createSystemServerClassLoader(systemServerClasspath,
                                                   parsedArgs.targetSdkVersion);
                Thread.currentThread().setContextClassLoader(cl);
            }
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);//2
        }
    }

SyetemServer进程是复制了Zygote进程的地址空间,因此也会得到Zygote进程创建的Socket,这个Socket对于SyetemServer进程没有用处,因此,需要注释1处的代码来关闭该Socket。在注释2处调用RuntimeInit的zygoteInit函数。


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

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        redirectLogStreams();
        commonInit();
        nativeZygoteInit();//1
        applicationInit(targetSdkVersion, argv, classLoader);//2
    }

注释1处调用nativeZygoteInit函数,很显然,这是一个Native层的代码。

启动Binder线程池

//frameworks/base/core/jni/AndroidRuntime.cpp

static const JNINativeMethod gMethods[] = {
    { "nativeFinishInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
    { "nativeZygoteInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
    { "nativeSetExitWithoutCleanup", "(Z)V",
        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};

nativeZygoteInit函数调用的JNI文件

通过JNI的gMethods数组,可以看出nativeZygoteInit函数对应的是JNI文件AndroidRuntime.cpp的com_android_internal_os_RuntimeInit_nativeZygoteInit函数

...
static AndroidRuntime* gCurRuntime = NULL;
...
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

这里gCurRuntime是AndroidRuntime类型的指针,AndroidRuntime的子类AppRuntime在app_main.cpp中定义

//frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();//1
    }

注释1处的代码用来启动一个Binder线程池,这样SyetemServer进程就可以使用Binder来与其他进程进行通信了。看到这里我们知道RuntimeInit.java的nativeZygoteInit函数主要做的就是启动Binder线程池。

invokeStaticMain
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
回到RuntimeInit.java的代码,在注释2处调用了applicationInit函数。

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
...
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

applicationInit函数中主要调用了invokeStaticMain函数。

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class cl;
        try {
            cl = Class.forName(className, true, classLoader);//1
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });//2
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }
        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);//3
    }

注释1处className为“com.android.server.SystemServer”,因此通过反射返回的cl为SystemServer类。注释2处找到SystemServer中的main函数。在注释3处将找到的main函数传入到MethodAndArgsCaller异常中并抛出该异常。截获MethodAndArgsCaller异常的代码在ZygoteInit.java的main函数中。

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

public static void main(String argv[]) {
       ...
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();//1
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

在注释1处调用了MethodAndArgsCaller的run函数。

public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
         ...
        }
    }
}

这里mMethod指的就是SystemServer的main函数,因此main函数被动态调用。

1、解析SystemServer进程

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

 public static void main(String[] args) {
        new SystemServer().run();
    }
main函数中只调用了SystemServer的run函数
private void run() {
        ...
            System.loadLibrary("android_servers");//1
        ...

            // Initialize the system context.
            createSystemContext();//2
            ...
            mSystemServiceManager = new SystemServiceManager(mSystemContext);//3
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        ...    
         try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();//4
            startCoreServices();//5
            startOtherServices();//6
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
        ...
    }

run函数代码,关键就是在注释1处加载了libandroid_servers.so。
注释2处创建 system context ,通过调用ActivityThread.systemMain()来创建一个ActivityThread来创建application一些相关的操作。
接下来在注释3处创建SystemServiceManager,创建实例,启动实例,管理实例的生命周期的一个类.系统中的服务就是调用SystemServiceManager中的startService方法通过service的类名来启动服务。通过类名,想必也就是反射来调用。
在注释4中的startBootstrapServices函数中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。这些服务是基础。有了这些东西,才能构建安卓中的四大组件。理解这些服务对app开发者来说更能深刻的理解一些上层api的调用。
在注释5处startCoreServices的函数中则启动了BatteryService、UsageStatsService和WebViewUpdateService。注释6处的startOtherServices函数中则启动了CameraService、AlarmManagerService、VrManagerService等服务,这些服务的父类为SystemService。

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

public <T extends SystemService> T startService(Class<T> serviceClass) {
  ...
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);//1
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            }
...
            // Register it.
            mServices.add(service);//2
            // Start it.
            try {
                service.onStart();
            } catch (RuntimeException ex) {
                throw new RuntimeException("Failed to start service " + name
                        + ": onStart threw an exception", ex);
            }
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

注释1处的代码用来创建SystemService,这里的SystemService是PowerManagerService,在注释2处将PowerManagerService添加到mServices中,这里mServices是一个存储SystemService类型的ArrayList。接着调用PowerManagerService的onStart函数启动PowerManagerService并返回,这样就完成了PowerManagerService启动的过程。

除了用mSystemServiceManager的startService函数来启动系统服务外,也可以通过如下形式来启动系统服务,以PackageManagerService

mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); 。

直接调用了PackageManagerService的main函数

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


public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    // Self-check for initial settings.
    PackageManagerServiceCompilerMapping.checkProperties();
    PackageManagerService m = new PackageManagerService(context, installer,
            factoryTest, onlyCore);//1
    m.enableSystemUserPackages();
    // Disable any carrier apps. We do this very early in boot to prevent the apps from being
    // disabled after already being started.
    CarrierAppUtils.disableCarrierAppsUntilPrivileged(context.getOpPackageName(), m,
            UserHandle.USER_SYSTEM);
    ServiceManager.addService("package", m);//2
    return m;
}

注释1处直接创建PackageManagerService并在注释2处将PackageManagerService注册到ServiceManager中,ServiceManager用来管理系统中的各种Service,用于系统C/S架构中的Binder机制通信:Client端要使用某个Service,则需要先到ServiceManager查询Service的相关信息,然后根据Service的相关信息与Service所在的Server进程建立通讯通路,这样Client端就可以使用Service了。

还有的服务是直接注册到ServiceManager中的
frameworks/base/services/java/com/android/server/SystemServer.java

telephonyRegistry = new TelephonyRegistry(context);
  ServiceManager.addService("telephony.registry", telephonyRegistry);

6、Launcher启动

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

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

private void startOtherServices() {
 ...
  mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                Slog.i(TAG, "Making services ready");
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_ACTIVITY_MANAGER_READY);

...
}
...
}

SyetemServer进程在启动的过程中会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。在此前已经启动的ActivityManagerService会将Launcher启动起来。 启动Launcher的入口为ActivityManagerService的systemReady函数

在startOtherServices函数中,会调用ActivityManagerService的systemReady函数

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

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

systemReady函数中调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数

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);//1
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        return false;
    }

在注释1处会调用ActivityStack的resumeTopActivityUncheckedLocked函数,ActivityStack对象是用来描述Activity堆栈的,resumeTopActivityUncheckedLocked函数如下所示。

frameworks/base/services/core/java/com/android/server/am/ActivityStack.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;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);//1
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
       return result;
    }

注释1调用了resumeTopActivityInnerLocked函数

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
   ...
   return isOnHomeDisplay() &&
                        mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
   ...                 
}

resumeTopActivityInnerLocked函数的代码很长,我们截取我们要分析的关键的一句:调用ActivityStackSupervisor的resumeHomeStackTask函数。

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

boolean startHomeActivityLocked(int userId, String reason) {
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {//1
            return false;
        }
        Intent intent = getHomeIntent();//2
        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.instrumentationClass == null) {//3
                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);//4
            }
        } else {
            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
        }

        return true;
    }

注释1处的mFactoryTest代表系统的运行模式,系统的运行模式分为三种,分别是非工厂模式、低级工厂模式和高级工厂模式,mTopAction则用来描述第一个被启动Activity组件的Action,它的值为Intent.ACTION_MAIN。因此注释1的代码意思就是mFactoryTest为FactoryTest.FACTORY_TEST_LOW_LEVEL(低级工厂模式)并且mTopAction=null时,直接返回false。注释2处的getHomeIntent函数如下所示。

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;
}

getHomeIntent函数中创建了Intent,并将mTopAction和mTopData传入。mTopAction的值为Intent.ACTION_MAIN,并且如果系统运行模式不是低级工厂模式则将intent的Category设置为Intent.CATEGORY_HOME。我们再回到ActivityManagerService的startHomeActivityLocked函数,假设系统的运行模式不是低级工厂模式,在注释3处判断符合Action为Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME的应用程序是否已经启动,如果没启动则调用注释4的方法启动该应用程序。 这个被启动的应用程序就是Launcher,因为Launcher的Manifest文件中的intent-filter标签匹配了Action为Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME。
这样,应用程序Launcher就会被启动起来,并执行它的onCreate函数。

7、总结


Android系统启动流程(nougat7.1.1_r6)_第5张图片

总结一下,Android系统启动流程如下:
1.启动电源以及系统启动 当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
2.引导程序BootLoader 引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
4.init进程启动 初始化和启动属性服务,并且启动Zygote进程。
6.SystemServer进程启动 启动Binder线程池和SystemServiceManager,并且启动各种系统服务。
7.Launcher启动 被SystemServer进程启动的ActivityManagerService会启动Launcher

你可能感兴趣的:(android系统源码)