Android系统启动流程

106 阅读22分钟

开机启动流程

init进程 –-> Zygote进程 –> SystemServer进程 –>应用进程

image.png

1. 第一个系统进程init

1.1 init进程是什么?

Linux系统的用户进程,是所有用户进程的鼻祖,进程号为1,它有许多重要的职责,比如创建Zygote孵化器和属性服务等。并且它是由多个源文件组成的,对应源码目录system/core/init中。

1.2 init进程启动核心代码流程分析

init进程的启动会首先从init进程的入口函数开始,init进程的入口函数main位于system/core/init/init.cpp中,代码如下所示:

int main(int argc, char** argv) {
​
    ...
    // 如果是初始化第一阶段,则需要执行下面的步骤1
    if (is_first_stage) {
        ...
​
        // 清理umask
        umask(0);
​
        ...
​
        // 1、创建和挂载启动所需的文件目录
        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));
        ...
​
        // 初识化Kernel的Log,获取外界的Kernel日志
        InitKernelLogging(argv);
​
        ...
    }
​
    // 初识化Kernel的Log,获取外界的Kernel日志
    InitKernelLogging(argv);
​
    ...
​
    // 2、初始化属性相关资源
    property_init();
​
    ...
​
    // 创建epoll句柄
    epoll_fd = epoll_createl(EPOLL_CLOEXEC);
    ...
​
    // 3、设置子信号处理函数
    sigchld_handler_init();
​
    // 导入默认的环境变量
    property_load_boot_defaults();
​
    // 4、启动属性服务
    start_property_service();
    set_usb_controller();
​
    ...
​
    // 加载引导脚本
    LoadBootScripts(am, sm);
​
    ...   
    while (true) {
​
        ...
​
        if (!(waiting_for_prop || Service::is_exec_service_running())) {
            // 内部会偏离执行每个action中携带的command对应的执行函数
            am.ExecuteOneCommand();
​
        }
        if (!(waiting_for_prop || Service::is_exec_service_running())) {
            if (!shutting_down) {
                // 重启死去的子进程
                auto next_process_restart_time = RestartProcesses();
​
                ...
            }
​
            // If there's more work to do, wake up again immediately.
            if (am.HasMoreCommands()) epoll_timeout_ms = 0;
        }
        epoll_event ev;
        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
        if (nr == -1) {
            PLOG(ERROR) << "epoll_wait failed";
        } else if (nr == 1) {
            ((void (*)()) ev.data.ptr)();
        }
    }
​
    return 0;
}
​
static void LoadBootScripts(ActionManager&action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);
​
    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    // bootscript默认是空的
    if (bootscript.empty()) {
        // 5、解析init.rc配置文件
        parser.ParseConfig("/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}

1.3 解析init.rc配置文件

parser.ParseConfig("/init.rc");
init.rc是什么?

它是由Android初始化语言编写的一个非常重要的配置脚本文件。Android初始化语言主要包含5种类型的语句:

  • Action(常用)
  • Service(常用)
  • Command
  • Option
  • Import

这里了解下Action和Service的格式:

on <trigger> [&& <trigger>]*     //设置触发器  
    <command>  
    <command>      //动作触发之后要执行的命令
    ...
​
​
service <name> <pathname> [ <argument> ]*   //<service的名字><执行程序路径><传递参数>  
    <option>       //option是service的修饰词,影响什么时候、如何启动services  
    <option>  
    ...

注意:Android8.0对init.rc文件进行了拆分,每个服务对应一个rc文件。

init.rc中的Action、Service语句都有相应的XXXParser类来解析,即ActionParser、ServiceParser。那么ServiceParser是如何解析Service语句的?

查看相应的XXXparser,即ServiceParser:

bool ServiceParser::ParseSection(const std::vector<std::string>& args,
                                 std::string* err) {
​
    // 判断Service是否有name和可执行程序                             
    if (args.size() < 3) {
        *err = "services must have a name and a     program";
        return false;
    }
​
    const std::string& name = args[1];
    if (!IsValidName(name)) {
        *err = StringPrintf("invalid service name     '%s'", name.c_str());
        return false;
    }
​
    std::vector<std::string> str_args(args.begin() + 2, args.end());
    // 1
    service_ = std::make_unique<Service>(name, str_args);
    return true;
}
​
​
bool ServiceParser::ParseLineSection(const std::vector<std::string>& args,
                                     const std::string&  filename, int line,
                                     std::string* err)  const {
    // 2                                 
    return service_ ? service_->ParseLine(args, err) : false;
}
​
void ServiceParser::EndSection() {
    if (service_) {
        // 3
        ServiceManager::GetInstance().AddService(std::move(service_));
    }
}
​
void ServiceManager::AddService(std::unique_ptr<Service> service) {
    Service* old_service = FindServiceByName(service->name());
    if (old_service) {
        ERROR("ignored duplicate definition of service '%s'",
            service->name().c_str());
        return;
    }
    services_.emplace_back(std::move(service));//1
}
  • 1、先使用ParseSection()方法根据参数创建出一个Service对象。
  • 2、再使用ParseLineSection()方法解析Service语句中的每一个子项,将其中的内容添加到Service对象中。
  • 3、然后,在解析完所有数据后,会调用EndSection函数,内部会执行ServiceManager的AddService函数,最终将Service对象加入vector类型的Service链表中。
init启动Zygote流程?

先看到init.rc的这部分配置代码:

...
on nonencrypted    
    exec - root -- /system/bin/update_verifier nonencrypted  
    // 1
    class_start main         
    class_start late_start 
...

1、使用class_start这个COMMAND去启动Zygote。其中class_start对应do_class_start()函数。

static Result<Success> do_class_start(const BuiltinArguments& args) {
    // Starting a class does not start services which are explicitly disabled.
    // They must be started individually.
    for (const auto& service : ServiceList::GetInstance()) {
        if (service->classnames().count(args[1])) {
            // 2
            if (auto result = service->StartIfNotDisabled(); !result) {
                LOG(ERROR) << "Could not start service'" << service->name()
                           << "' as part of class '" <<  args[1] << "': " <<  result.error();
            }
        }
    }
    return Success();
}

2、在system/core/init/builtins.cpp的do_class_start()函数中会遍历前面的Vector类型的Service链表,找到classname为main的Zygote,并调用system/core/init/service.cpp中的startIfNotDisabled()函数。

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

3、如果Service没有再其对应的rc文件中设置disabled选项,则会调用Start()启动该Service。

bool Service::Start() {
​
    ...
​
​
    if (flags_ & SVC_RUNNING) {
        if ((flags_ & SVC_ONESHOT) && disabled) {
            flags_ |= SVC_RESTART;
        }
        // 如果不是一个错误,尝试去启动一个已经启动的服务
        return Success();
    }
​
    ...
​
    // 判断需要启动的Service的对应的执行文件是否存在,不存在则不启动该Service
    struct stat sb;
    if (stat(args_[0].c_str(), &sb) == -1) {
        flags_ |= SVC_DISABLED;
        return ErrnoError() << "Cannot find '" << args_[0] << "'";
    }
​
    ...
​
    // fork函数创建子进程
    pid_t pid = fork();
    // 运行在子进程中
    if (pid == 0) {
        umask(077);
        ...
​
        // 在ExpandArgsAndExecv函数里进行了参数装配并使用了execve()执行程序
        if (!ExpandArgsAndExecv(args_)) {
            PLOG(ERROR) << "cannot execve('" << args_[0] << "')";
        }
​
         _exit(127);
    }
    ...
    return true;
}
​
static bool ExpandArgsAndExecv(cons std::vector<std::string>& args) {
    std::vector<std::string> expanded_args;
    std::vector<char*> c_strings;
​
    expanded_args.resize(args.size());
    c_strings.push_back(const_cast<char*>(args[0].data()));
    for (std::size_t i = 1; i < args.size(); ++i) {
        if (!expand_props(args[i], &expanded_args[i])) {
            LOG(FATAL) << args[0] << ": cannot expand '" << args[i] << "'";
        }
        c_strings.push_back(expanded_args[i].data());
    }
    c_strings.push_back(nullptr);
​
    // 最终通过execve执行程序
    return execv(c_strings[0], c_strings.data()) == 0;
}

4、在Start()函数中,如果Service已经运行,则不再启动。如果没有,则使用fork()函数创建子进程,并返回pid值。当pid为0时,则说明当前代码逻辑在子进程中运行,最然后会调用execve()函数去启动子进程,并进入该Service的main函数中,如果该Service是Zygote,则会执行Zygote的main函数。(对应frameworks/base/cmds/app_process/app_main.cpp中的main()函数)

int main(int argc, char* const argv[])
{
    ...
    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.");
    }
}

5、最后,调用runtime的start函数启动Zygote。

1.4 总结

经过以上的分析,init进程的启动过程主要分为以下三部:

  • 1、创建和挂载启动所需的文件目录。
  • 2、初始化和启动属性服务。
  • 3、解析init.rc配置文件并启动Zygote进程。

2. 系统关键服务的启动

作为Android系统的第一个进程,init通过解析init.rc来陆续启动其他的关键的系统服务进程---其中最重要的是ServiceManager,Zygote和SystemServer。

2.1 Android的“DNS服务器” --ServiceManager

ServiceManager是Binder机制中的“DNS服务器”,负责域名(某Binder服务在ServiceManger注册时提供的名称)到IP地址(由底层Binder驱动分配的值)的解析。

2.2 孕育新的线程和进程 --Zygote

在init启动Zygote时主要是调用app_main.cpp的main函数中的AppRuntime.start()方法来启动Zygote进程的,我们先看到app_main.cpp的main函数:

int main(int argc, char* const argv[])
{
    ...
    while (i < argc) {
        const char* arg = argv[i++];
        // 1
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            // 2
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            // 3
            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;
        }
    }
​
    ...
​
    // 4
    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进程都是通过fork自身来创建子进程的,这样Zygote进程和由它fork出来的子进程都会进入app_main.cpp的main函数中,所以在mian函数中,首先会判断当前运行在哪个进程,在注释1处,会判断参数arg中释放包含了”–zygote”,如果包含了,则说明main函数是运行在Zygote进程中的并会将zygote标记置为true。在注释2处会判断参数arg中是否包含了”–start-system-server”,如果包含了则表示当前是处在SystemServer进程中并将startSystemServer设置为true。同理在注释3处会判断参数arg是否包含”–application”,如果包含了说明当前处在应用程序进程中并将application标记置为true。最后在注释4处,当zygote标志是true的时候,也就是当前正处在Zygote进程中时,则使用AppRuntime.start()函数启动Zygote进程。

我们接着看看AndroidRuntime的start函数:

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;
    // 1
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);
​
    /*
     * 2、Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
​
    ...
    // 3
    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);
    }
​
    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    // 4
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        // 6
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            // 6
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
​
#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    free(slashClassName);
​
    ...
}

首先,在AndroidRuntime的start函数中,会现在注释1处使用startVm函数来启动弄Java虚拟机,然后在注释2处使用startReg函数为Java虚拟机注册JNI方法。在注释3处的classNameStr是传入的参数,值为com.android.internall.os.ZygoteInit。然后在注释4处使用toSlashClassName函数将className的”.”替换为”/“,替换后的值为com/android/internal/os/ZygoteInit。接着根据这个值找到ZygoteInit并在注释5处找到ZygoteInit的main函数,最后在注释6处使用JNI调用ZygoteInit的main函数,之所以这里要使用JNI,是因为ZygoteInit是java代码。最终,Zygote就从Native层进入了Java FrameWork层。在此之前,并没有任何代码进入Java FrameWork层面,因此可以认为,Zygote开创了java FrameWork层。

接着,我们看看Zygoteinit.java中的main方法:

 public static void main(String argv[]) {
​
    ...
​
    try {
        ...
​
        // 1
        zygoteServer.registerServerSocketFromEnv(socketName);
        // In some configurations, we avoid preloading resources and classes eagerly.
        // In such cases, we will preload things prior to our first fork.
        if (!enableLazyPreload) {
            bootTimingsTraceLog.traceBegin("ZygotePreload");
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
​
            // 2
            preload(bootTimingsTraceLog);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());
            bootTimingsTraceLog.traceEnd(); // ZygotePreload
        } else {
            Zygote.resetNicePriority();
        }
​
        ...
​
        if (startSystemServer) {
            // 3
            Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
​
            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
            // child (system_server) process.
            if (r != null) {
                r.run();
                return;
            }
        }
​
        Log.i(TAG, "Accepting command socket connections");
​
        // The select loop returns early in the child process after a fork and
        // loops forever in the zygote.
        // 4
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        zygoteServer.closeServerSocket();
    }
​
    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
    if (caller != null) {
        caller.run();
    }
}

首先,在注释1处调用了ZygoteServer的registerServerSocketFromEnv方法创建了一个名为”zygote”的Server端的Socket,它用来等待ActivityManagerService请求Zygote来创建新的应用程序进程。

首先,在注释1处调用了ZygoteServer的registerServerSocketFromEnv方法创建了一个名为”zygote”的Server端的Socket,它用来等待ActivityManagerService请求Zygote来创建新的应用程序进程。我首先分析下registerServerSocketFromEnv方法的处理逻辑,源码如下所示:

private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
​
void registerServerSocketFromEnv(String socketName) {
    if (mServerSocket == null) {
        int fileDesc;
        // 1
        final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
        try {
            // 2
            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);
            // 3
            mServerSocket = new LocalServerSocket(fd);
            mCloseSocketFd = true;
        } catch (IOException ex) {
            throw new RuntimeException(
                    "Error binding to local socket '" + fileDesc + "'", ex);
        }
    }
}

首先,会在注释1处将Socket的名字拼接为“ANDROID_SOCKET_zygote“,在注释2处调用System.getenv()方法得到该Socket对应的环境变量中的值,然后将这个Socket环境变量值解析为int类型的文件描述符参数。接着,在注释4处,使用上面得到的文件描述符参数得到一个文件描述符,并由此新建一个服务端Socket。当Zygote进程将SystemServer进程启动红藕,就会在这个服务端Socket上等待AMS请求Zygote进程去创建新的应用程序进程。

接着,我们回到ZygoteInit的main方法,在注释2处会预加载类和资源。然后在注释3处,使用了forkSystemServer()方法去创建SystemServer进程。forkSystemServer()方法核心代码如下所示:

private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
​
    // 一系统创建SystemServer进程所需参数的准备工作
​
    try {
        ...
​
        /* Request to fork the system server process */
        // 3.1
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.runtimeFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
​
    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
​
        zygoteServer.closeServerSocket();
​
        // 3.2
        return handleSystemServerProcess(parsedArgs);
    }
​
    return null;
}

可以看到,forkSystemServer()方法中,注释3.1调用了Zygote的forkSystemServer()方法去创建SystemServer进程,其内部会执行nativeForkSystemServer这个Native方法,它最终会使用fork函数在当前进程创建一个SystemServer进程。如果pid等于0,即当前是处于新创建的子进程ServerServer进程中,则在注释3.2处使用handleSystemServerProcess()方法处理SystemServer进程的一些处理工作。

2.2.1 总结

从以上的分析可以得知,Zygote进程启动中承担的主要职责如下:

  • 1、创建AppRuntime,执行其start方法,启动Zygote进程。。
  • 2、创建JVM并为JVM注册JNI方法。
  • 3、使用JNI调用ZygoteInit的main函数进入Zygote的Java FrameWork层。
  • 4、使用registerZygoteSocket方法创建服务器端Socket,并通过runSelectLoop方法等等AMS的请求去创建新的应用进程。
  • 5、启动SystemServer进程。

2.3 SystemServer的启动

2.3.1 Zygote处理SystemServer进程

由前文可知,在ZygoteInit的forkSystemServer()方法中启动了SystemServer进程,如下所示:

private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
​
    ...
​
    try {
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
​
        boolean profileSystemServer = SystemProperties.getBoolean(
                "dalvik.vm.profilesystemserver", false);
        if (profileSystemServer) {
            parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
        }
​
        /* Request to fork the system server process */
        // 1
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.runtimeFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
​
    /* For child process */
    // 2
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        // 3
        zygoteServer.closeServerSocket();
        // 4
        return handleSystemServerProcess(parsedArgs);
    }
​
    return null;
}

在注释1处,调用了Zygote的forkSystemServer()方法创建了SystemServer进程,并返回了当前进程的pid。在注释2处,如果pid==0则说明Zygote进程创建SystemServer进程成功,当前运行在SystemServer进程中。接着,在注释3处,由于SystemServer进程fork了Zygote进程的地址空间,所以会得到Zygote进程创建的Socket,这个Socket对于SystemServer进程是无用的,因此,在此处关闭了该Socket。最后,在注释4处,调用了handleSystemServerprocess()方法来启动SystemServer进程。handleSystemServerProcess()方法如下所示:

/**
 * Finish remaining work for the newly forked system server process.
 */
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
​
    ...
​
    if (parsedArgs.invokeWith != null) {
​
        ...
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            // 1
            cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
​
            Thread.currentThread().setContextClassLoader(cl);
        }
​
        /*
         * Pass the remaining arguments to SystemServer.
         */
        // 2
        return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }
}

在注释1处,使用了systemServerClassPath和targetSdkVersion创建了一个PathClassLoader。接着,在注释2处,执行了ZygoteInit的zygoteInit()方法,该方法如下所示:

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

在zygoteInit()方法中,首先在注释1处执行了nativeZygoteInit()方法,这里看到方法前缀为native可知是一个本地函数,因此,我们先了解它对应的JNI文件,在AndroidRuntime.cpp类中可以查看到nativeZygoteInit()方法对应的native函数,如下所示:

/*
* JNI registration.
*/
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}

这里使用了JNI动态注册的方式,将nativeZygoteInit()方法和native函数com_android_internal_os_ZygoteInit_nativeZygoteInit()建立了映射关系,我们看到这个native方法的代码:

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

可以看到,gCurRuntime是AndroidRuntime类型的指针,具体指向的是其子类AppRuntime,它在app_main.cpp中定义,代码如下所示:

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

在注释1处,创建了一个ProcessState实例, 在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binder驱动,建立线程池,让其进程里面的所有线程都能通过Binder通信。在注释2处,调用了ProcessState实例的startThreadPool()函数启动了一个Binder线程池,其实里面最终会调用到IPCThreadState实例的joinThreadPool()函数进程Binder线程池相关的处理。现在,我们再回到zygoteInit()方法的注释2处,这里调用了RuntimeInit的applicationInit()方法,代码如下所示:

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
    ClassLoader classLoader) {
​
    ...
​
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

在applicationInit()方法中最后调用了findStaticMain()方法:

protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;
​
    try {
        // 1
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }
​
    Method m;
    try {
        // 2
        m = cl.getMethod("main", new Class[] { String[].class });
    } 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);
    }
​
    /*
     * 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.
     */
    // 3
    return new MethodAndArgsCaller(m, argv);
}

首先,在注释1处,通过发射得到了SystemServer类。接着,在注释2处,找到了SystemServer中的main()方法。最后,在注释3处,会将main()方法传入MethodAndArgsCaller()方法中,这里的MethodAndArgsCaller()方法是一个Runnable实例,它最终会一直返回出去,直到在ZygoteInit的main()方法中被使用,如下所示:

if (startSystemServer) {
    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
​
    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
    // child (system_server) process.
    if (r != null) {
        r.run();
        return;
    }
}

可以看到,最终直接调用了这个Runnable实例的run()方法,代码如下所示:

/**
 * Helper class which holds a method and arguments and can call them. This is used as part of
 * a trampoline to get rid of the initial process setup stack frames.
 */
static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;
​
    /** argument array */
    private final String[] mArgs;
​
    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }
​
    public void run() {
        try {
            // 1
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

在注释1处,这个mMethod就是指的SystemServer的main()方法,这里动态调用了SystemServer的main()方法,最终,SystemServer进程就进入了SystemServer的main()方法中了。这里还有个遗留问题,为什么不直接在findStaticMain()方法中直接动态调用SystemServer的main()方法呢?原因就是这种递归返回后再执行入口方法的方式会让SystemServer的main()方法看起来像是SystemServer的入口方法,而且,这样也会清除之前所有SystemServer相关设置过程中需要的堆栈帧。

2.3.2 SystemServer进程解析

接下来我们看看SystemServer的main()方法:

/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
    new SystemServer().run();
}

main()方法中调用了SystemServer的run()方法,如下所示:

private void run() {
    try {
        ...
​
        // 1
        Looper.prepareMainLooper();
        ...
​
        // Initialize native services.
        // 2
        System.loadLibrary("android_servers");
​
        // Check whether we failed to shut down last time we tried.
        // This call may not return.
        performPendingShutdown();
​
         // Initialize the system context.
        createSystemContext();
​
        // Create the system service manager.
        // 3
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }
​
    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        // 4
        startBootstrapServices();
        // 5
        startCoreServices();
        // 6
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }
​
    ...
​
    // Loop forever.
    // 7
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

在注释1处,创建了消息Looper。

在注释2处,加载了动态库libandroid_servers.so。

接着,在注释3处,创建了SystemServerManager,它的作用是对系统服务进行创建、启动和生命周期管理。

在注释4处的startBootstarpServices()方法中使用SystemServiceManager启动了ActivityManagerService、PackageManagerService、PowerManagerService等引导服务。

在注释5处的startCoreServices()方法中则启动了BatteryService、WebViewUpdateService、DropBoxManagerService、UsageStatsService4个核心服务。

在注释6处的startOtherServices()方法中启动了WindowManagerService、InputManagerService、CameraService等其它服务。

这些服务的父类都是SystemService。

可以看到,上面把系统服务分成了三种类型:引导服务、核心服务、其它服务。这些系统服务共有100多个,其中对于我们来说比较关键的有:

  • 引导服务:ActivityManagerService,负责四大组件的启动、切换、调度。
  • 引导服务:PackageManagerService,负责对APK进行安装、解析、删除、卸载等操作。
  • 引导服务:PowerManagerService,负责计算系统中与Power相关的计算,然后决定系统该如何反应。
  • 核心服务:BatteryService,管理电池相关的服务。
  • 其它服务:WindowManagerService,窗口管理服务。
  • 其它服务:InputManagerService,管理输入事件。

很多系统服务的启动逻辑都是类似的,这里我以启动ActivityManagerService服务来进行举例,代码如下所示:

mActivityManagerService = mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService();

SystemServiceManager的startService()方法启动了ActivityManagerService,该启动方法如下所示:

@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        final String name = serviceClass.getName();
​
        ...
​
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            // 1
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
​
        ...
​
        // 2
        startService(service);
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

在注释1处使用反射创建了ActivityManagerService实例,并在注释2处调用了另一个startService()重载方法,如下所示:

public void startService(@NonNull final SystemService service) {
    // Register it.
    // 1
    mServices.add(service);
    // Start it.
    long time = SystemClock.elapsedRealtime();
    try {
        // 2
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}

在注释1处,首先会将ActivityManagerService添加在mServices中,它是一个存储SystemService类型的ArrayList,这样就完成了ActivityManagerService的注册。在注释2处,调用了ActivityManagerService的onStart()方法完成了启动ActivityManagerService服务。

除了使用SystemServiceManager的startService()方法来启动系统服务外,也可以直接调用服务的main()方法来启动系统服务,如PackageManagerService:

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

这里直接调用了PackageManagerService的main()方法:

public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    // Self-check for initial settings.
    PackageManagerServiceCompilerMapping.checkProperties();
​
    // 1
    PackageManagerService m = new PackageManagerService(context, installer,
            factoryTest, onlyCore);
    m.enableSystemUserPackages();
    // 2
    ServiceManager.addService("package", m);
    // 3
    final PackageManagerNative pmn = m.new PackageManagerNative();
    ServiceManager.addService("package_native", pmn);
    return m;
}

在注释1处,直接新建了一个PackageManagerService实例,并在注释2处将PackageManagerService注册到服务大管家ServiceManager中,ServiceManager用于管理系统中的各种Service,用于系统C/S架构中的Binder进程间通信,即如果Client端需要使用某个Servcie,首先应该到ServiceManager查询Service的相关信息,然后使用这些信息和该Service所在的Server进程建立通信通道,这样Client端就可以服务端进程的Service进行通信了。

2.3.3 SystemServer总结

SystemService的启动流程分析至此已经完结,经过以上的分析可知,SystemService进程被创建后,主要的处理如下:

  • 1、启动Binder线程池,这样就可以与其他进程进行Binder跨进程通信。
  • 2、创建SystemServiceManager,它用来对系统服务进行创建、启动和生命周期管理。
  • 3、启动各种系统服务:引导服务、核心服务、其他服务,共100多种。应用开发主要关注引导服务ActivityManagerService、PackageManagerService和其他服务WindowManagerService、InputManagerService即可。

3. Launcher进程启动

Launcher作为Android系统的桌面,它的作用有两点:

  • 1、作为Android系统的启动器,用于启动应用程序。
  • 2、作为Android系统的桌面,用于显示和管理应用程序的快捷图标或者其它桌面组件。

下面,我们从以下两个方面来分析Launcher的启动过程:

  • 1、Launcher启动流程
  • 2、Launcher中应用图标的显示过程

3.1 Launcher启动过程分析

SystemServer进程在启动的过程中会启动PMS,PMS启动后会将系统中的应用程序安装完成,先前已经启动的AMS会将Launcher启动起来。在SystemServer的startOtherServices()方法中,调用了AMS的systemReady()方法,此即为Launcher的入口,如下所示:

private void startOtherServices() {
    ...
​
    mActivityManagerService.systemReady(() -> {
        Slog.i(TAG, "Making services ready");
        traceBeginAndSlog("StartActivityManagerReadyPhase");
        mSystemServiceManager.startBootPhase(
                SystemService.PHASE_ACTIVITY_MANAGER_READY);
​
        ...
        }
    ...
}

在Android 8.0及以上的部分源码中,都引入了Java Lambda表达式,可见其重要性的上升。下面继续分析AMS的systemReady()方法:

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

在systemReady()方法中继续调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked()方法,如下所示:

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

最终,调用了注释1处ActivityStack(描述Acitivity堆栈)的resumeTopActivityUncheckedLocked()方法,如下所示:

@GuardedBy("mService")
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;
        // 1
        result = resumeTopActivityInnerLocked(prev, options);
​
        // 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. In the case where the Activity will be
        // shown regardless of the lock screen, the call to
        // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
            checkReadyForSleep();
        }
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
​
     return result;
}

在注释1处调用了resumeTopActivityInnerLocked()方法,如下所示:

@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ...
​
     if (!hasRunningActivity) {
        // There are no activities left in the stack, let's look somewhere else.
        return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
    }
​
    ...
}

resumeTopActivityInnerLocked()方法非常长,大概有好几百行代码,但是对于主要流程来说最关键的就是在其中调用了resumeTopActivityInNextFocusableStack()方法,如下所示:

private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
        ActivityOptions options, String reason) {
    if (adjustFocusToNextFocusableStack(reason)) {
        // Try to move focus to the next visible stack with a running activity if this
        // stack is not covering the entire screen or is on a secondary display (with no home
        // stack).
        return mStackSupervisor.resumeFocusedStackTopActivityLocked(
                mStackSupervisor.getFocusedStack(), prev, null);
    }
​
    // Let's just start up the Launcher...
    ActivityOptions.abort(options);
    if (DEBUG_STATES) Slog.d(TAG_STATES,
            "resumeTopActivityInNextFocusableStack: " + reason + ", go home");
    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    // Only resume home if on home display
    // 1
    return isOnHomeDisplay() &&
            mStackSupervisor.resumeHomeStackTask(prev, reason);
}

在注释1处,调用了ActivityStackSupervisor的resumeHomeStackTask()方法,如下所示:

boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
    ...
​
    // Only resume home activity if isn't finishing.
    if (r != null && !r.finishing) {
        moveFocusableActivityStackToFrontLocked(r, myReason);
        return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
    }
    // 1
    return mService.startHomeActivityLocked(mCurrentUser, myReason);
}

注释1处,调用了AMS的startHomeActivityLocked()方法,如下所示:

boolean startHomeActivityLocked(int userId, String reason) {
    // 1
    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;
    }
​
    // 2
    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);
​
        // 3
        if (app == null || app.instr == null) {
            intent.setFlags(intent.getFlags() | 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;
​
            // 4
            mActivityStartController.startHomeActivity(intent, aInfo, myReason);
        }
    } else {
        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
    }
​
    return true;
}

首先,会在注释1处判断工厂模式和mTopAction的值,这里的工厂模式mFactoryTest代表的了系统的运行模式,它分为三种:

  • 1、非工厂模式
  • 2、低级工厂模式
  • 3、高级工厂模式

而mTopAction是来描述第一个被启动Activity组件的Action,默认值为Intent.ACTION_MAIN。所以,此时可知当mFactoryTest为低级工厂模式并且mTopAction为空时,则返回false。接着,在注释2处,调用了getHomeintent()方法,如下所示:

Intent getHomeIntent() {
    // 1
    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) {
        // 2
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    return intent;
}

在getHomeIntent()方法的注释1处,根据mTopAction和mTopData创建了Intent。注释2处,会判断如果系统运行模式不是低级工厂模式,则会将Category设置为Intent.CATEGORY_HOME,最后返回该Intent。

我们再回到AMS的startHomeActivityLocked()方法的注释3处,这里会判断符合上述Intent的应用程序是否已经启动,如果没有启动,则会在注释4处调用ActivityStartController的startHomeActivity()方法启动该应用程序,即Launcher。下面我们继续看看startHomeActivity()方法,如下所示:

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
    // 1
    mSupervisor.moveHomeStackTaskToTop(reason);
​
    // 2
    mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
            .setOutActivity(tmpOutRecord)
            .setCallingUid(0)
            .setActivityInfo(aInfo)
            .execute();
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    if (mSupervisor.inResumeTopActivity) {
        // If we are in resume section already, home activity will be initialized, but not
        // resumed (to avoid recursive resume) and will stay that way until something pokes it
        // again. We need to schedule another resume.
        mSupervisor.scheduleResumeTopActivities();
    }
}

注释1处,会将Launcher放入HomeStack中,它是ActivityStackSupervisor中用于存储Launcher的变量。然后,在注释2处调用了obtainStarter()方法,如下所示:

**
 * @return A starter to configure and execute starting an activity. It is valid until after
 *         {@link ActivityStarter#execute} is invoked. At that point, the starter should be
 *         considered invalid and no longer modified or used.
 */
ActivityStarter obtainStarter(Intent intent, String reason) {
    return mFactory.obtain().setIntent(intent).setReason(reason);
}

可知这里最终会返回一个配置好指定intent和reason和ActivityStarter,当它调用execute()方法时,则会启动Launcher,如下所示:

int execute() {
    try {
        // TODO(b/64750076): Look into passing request directly to these methods to allow
        // for transactional diffs and preprocessing.
        if (mRequest.mayWait) {
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                    mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                    mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                    mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                    mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        } else {
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                    mRequest.outActivity, mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        }
    } finally {
        onExecutionComplete();
    }
}

可以看到,这里调用了startActivity()方法来启动Launcher,最终会进入Launcher的onCreate()方法,Launcher启动完成。

3.2 Launcher中应用图标的显示过程

应用程序图标是进入应用程序的入口,接下来我们了解一下Launcher是如何显示应用程序图标的。首先从Launcher的onCreate()方法开始,如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
​
    // 1
    LauncherAppState app = LauncherAppState.getInstance(this);
    mOldConfig = new Configuration(getResources().getConfiguration());
​
    // 2
    mModel = app.setLauncher(this);
    initDeviceProfile(app.getInvariantDeviceProfile());
​
    ...
​
    // We only load the page synchronously if the user rotates (or triggers a
    // configuration change) while launcher is in the foreground
    int currentScreen = PagedView.INVALID_RESTORE_PAGE;
    if (savedInstanceState != null) {
        currentScreen = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN, currentScreen);
    }
​
    // 3
    if (!mModel.startLoader(currentScreen)) {
        if (!internalStateHandled) {
            // If we are not binding synchronously, show a fade in animation when
            // the first page bind completes.
            mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
        }
    } else {
        // Pages bound synchronously.
        mWorkspace.setCurrentPage(currentScreen);
​
        setWorkspaceLoading(true);
    }
​
}

首先,在注释1处得到LauncherAppState的实例,在注释2处,调用了它的setLauncher()方法将Launcher对象传进去,setLauncher()方法如下所示:

 LauncherModel setLauncher(Launcher launcher) {
    getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);
    mModel.initialize(launcher);
    return mModel;
}

在setLauncher()方法里面继续调用了LauncherModel的initialize()方法,如下所示:

/**
* Set this as the current Launcher activity object for the loader.
*/
public void initialize(Callbacks callbacks) {
    synchronized (mLock) {
        Preconditions.assertUIThread();
        mCallbacks = new WeakReference<>(callbacks);
    }
}

从此处我们可以得知Launcher被封装成了一个弱引用对象mCallbacks。我们再回到Launcher的onCreate()方法的注释3处的LauncherModel的startLoader()方法,如下所示:

// 1
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
    sWorkerThread.start();
}
​
// 2
@Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper());
​
public boolean startLoader(int synchronousBindPage) {
    // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
    InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_LOADER_RUNNING);
    synchronized (mLock) {
        // Don't bother to start the thread if we know it's not going to do anything
        if (mCallbacks != null && mCallbacks.get() != null) {
            final Callbacks oldCallbacks = mCallbacks.get();
            // Clear any pending bind-runnables from the synchronized load process.
            mUiExecutor.execute(oldCallbacks::clearPendingBinds);
​
            // If there is already one running, tell it to stop.
            stopLoader();
​
            // 3
            LoaderResults loaderResults = new LoaderResults(mApp, sBgDataModel,
                    mBgAllAppsList, synchronousBindPage, mCallbacks);
            if (mModelLoaded && !mIsLoaderTaskRunning) {
                // Divide the set of loaded items into those that we are binding synchronously,
                // and everything else that is to be bound normally (asynchronously).
                loaderResults.bindWorkspace();
                // For now, continue posting the binding of AllApps as there are other
                // issues that arise from that.
                loaderResults.bindAllApps();
                loaderResults.bindDeepShortcuts();
                loaderResults.bindWidgets();
                return true;
            } else {
                // 4
                startLoaderForResults(loaderResults);
            }
        }
    }
    return false;
}

在注释1处,新建了具有消息循环的线程HandlerThread对象。注释2处,新建了Handler,并传入了HandlerThread的Looper,此处Handler就是用于向HandlerThread发送消息。接着,在注释3处,创建了LoaderResults,在注释4处,调用了startLoaderForResults()方法并将LoaderResults传入,如下所示:

public void startLoaderForResults(LoaderResults results) {
    synchronized (mLock) {
        stopLoader();
        mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, results);
        runOnWorkerThread(mLoaderTask);
    }
}

在startLoaderForResults()方法中,调用了runOnWorkerThread(),如下所示:

/** Runs the specified runnable immediately if called from the worker thread, otherwise it is
 * posted on the worker thread handler. */
private static void runOnWorkerThread(Runnable r) {
    // 1
    if (sWorkerThread.getThreadId() == Process.myTid()) {
        // 2
        r.run();
    } else {
        // If we are not on the worker thread, then post to the worker handler
        // 3
        sWorker.post(r);
    }
}

首先,注释1处会先判断当前的执行线程是否是工作线程,如果是则直接调用注释2处Runnable的run()方法,否则,调用sWorker这个Handler对象的post()方法将LoaderTask作为消息发送给HandlerThread。接下来,我们看看LoaderTask,它实现了Runnable接口,当其所描述的消息被处理时,则会调用它的run()方法,如下所示:

/**
* Runnable for the thread that loads the contents of the launcher:
*   - workspace icons
*   - widgets
*   - all apps icons
*   - deep shortcuts within apps
*/
public class LoaderTask implements Runnable {
​
    ...
​
     synchronized (this) {
        // Skip fast if we are already stopped.
        if (mStopped) {
            return;
        }
    }
​
    TraceHelper.beginSection(TAG);
    try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
        TraceHelper.partitionSection(TAG, "step 1.1: loading workspace");
        // 1
        loadWorkspace();
​
        verifyNotStopped();
        TraceHelper.partitionSection(TAG, "step 1.2: bind workspace workspace");
        // 2
        mResults.bindWorkspace();
​
        // Notify the installer packages of packages with active installs on the first screen.
        TraceHelper.partitionSection(TAG, "step 1.3: send first screen broadcast");
        sendFirstScreenActiveInstallsBroadcast();
​
        // Take a break
        TraceHelper.partitionSection(TAG, "step 1 completed, wait for idle");
        waitForIdle();
        verifyNotStopped();
​
        // second step
        TraceHelper.partitionSection(TAG, "step 2.1: loading all apps");
        // 3
        loadAllApps();
​
​
        TraceHelper.partitionSection(TAG, "step 2.2: Binding all apps");
        verifyNotStopped();
        // 4
        mResults.bindAllApps();
​
        ...
     } catch (CancellationException e) {
        // Loader stopped, ignore
        TraceHelper.partitionSection(TAG, "Cancelled");
    }
    TraceHelper.endSection(TAG);
}

Launcher是用工作区的形式来显示系统安装的应用程序快捷图标的,每一个工作区都是用来描述一个抽象桌面的,它由n个屏幕组成,每个屏幕又分为n个单元格,每个单元格用来显示一个应用程序的快捷图标。

首先,在注释1、2处调用了loadWorkSpace()和LoaderResults的bindWorkspace()方法来加载和绑定工作区信息。注释3处调用了loadAllApps()和LoaderResults的bindAllApps()方法来加载系统已经安装的应用程序信息,bindAllApps()方法如下所示:

public void bindAllApps() {
    // shallow copy
    @SuppressWarnings("unchecked")
    final ArrayList<AppInfo> list = (ArrayList<AppInfo>) mBgAllAppsList.data.clone();
​
    Runnable r = new Runnable() {
        public void run() {
            // 1
            Callbacks callbacks = mCallbacks.get();
            if (callbacks != null) {
                // 2
                callbacks.bindAllApplications(list);
            }
        }
    };
    // 3
    mUiExecutor.execute(r);
}

首先,在注释1处会从mCallbacks这个Launcher的弱引用对象中取出Launcher对象,并在注释2处调用了它的bindAllApplication()来绑定所有的应用程序信息,最后在注释3处使用mUiExecutor这个MainThreadExecutor执行器对象去执行这个创建好的Runnable对象。接下来,我们看看Launcher的bindAllApplications()方法,如下所示:

// Main container view for the all apps screen.
@Thunk AllAppsContainerView mAppsView;
​
/**
* Add the icons for all apps.
*
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindAllApplications(ArrayList<AppInfo> apps) {
    // 1
    mAppsView.getAppsStore().setApps(apps);
​
    if (mLauncherCallbacks != null) {
        mLauncherCallbacks.bindAllApplications(apps);
    }
}

在注释1处,调用了AllAppsContainerView的getAppsStore()方法得到了一个AllAppsStore对象,AllAppsContainerView是所有App屏幕的主容器视图,AllAppsStore是一个负责维护所有app信息集合的通用工具类。下面,我们看看AllAppsStore对象的setApps()方法:

/**
 * Sets the current set of apps.
 */
public void setApps(List<AppInfo> apps) {
    mComponentToAppMap.clear();
    addOrUpdateApps(apps);
}

这里继续调用了addOrUpdateApps()方法:

 private final HashMap<ComponentKey, AppInfo> mComponentToAppMap = new HashMap<>();
​
/**
* Adds or updates existing apps in the list
*/
public void addOrUpdateApps(List<AppInfo> apps) {
    for (AppInfo app : apps) {
        mComponentToAppMap.put(app.toComponentKey(), app);
    }
    notifyUpdate();
}

可以看到,最终将所有app信息保存在了AllAppsStore的HashMap容器中。

当AllAppsContainerView加载完XML布局时,会调用自身的onFinishInflate()方法,如下所示:

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
​
    // This is a focus listener that proxies focus from a view into the list view.  This is to
    // work around the search box from getting first focus and showing the cursor.
    setOnFocusChangeListener((v, hasFocus) -> {
        if (hasFocus && getActiveRecyclerView() != null) {
            getActiveRecyclerView().requestFocus();
        }
    });
​
    mHeader = findViewById(R.id.all_apps_header);
​
    // 1
    rebindAdapters(mUsingTabs, true /* force */);
​
    mSearchContainer = findViewById(R.id.search_container_all_apps);
    mSearchUiManager = (SearchUiManager) mSearchContainer;
    mSearchUiManager.initialize(this);
}

在注释1处,进行了适配器数据的绑定,我们继续查看rebindAdapters()方法:

private void rebindAdapters(boolean showTabs) {
    rebindAdapters(showTabs, false /* force */);
}
​
private void rebindAdapters(boolean showTabs, boolean force) {
    ...
​
    if (mUsingTabs) {
        // 1
        mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
        mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
        onTabChanged(mViewPager.getNextPage());
    } else {
        // 2
        mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
        mAH[AdapterHolder.WORK].recyclerView = null;
    }
    setupHeader();
​
    ...
}

可以看到,不管是否正在使用标签,最终都会调用到AdapterHolder的setup()方法,它时AllAppsContainerView的内部类,如下所示:

void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) {
        appsList.updateItemFilter(matcher);
        recyclerView = (AllAppsRecyclerView) rv;
        recyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
​
        // 1
        recyclerView.setApps(appsList, mUsingTabs);
        recyclerView.setLayoutManager(layoutManager);
​
        // 2
        recyclerView.setAdapter(adapter);
        recyclerView.setHasFixedSize(true);
        // No animations will occur when changes occur to the items in this RecyclerView.
        recyclerView.setItemAnimator(null);
        FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(recyclerView);
        recyclerView.addItemDecoration(focusedItemDecorator);
        adapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
        applyVerticalFadingEdgeEnabled(verticalFadingEdge);
        applyPadding();
    }

注释1处,会将app信息列表appsList设置给AllAppsRecyclerView对象,在注释2处,为其设置了Adapter。最终,应用程序快捷图标列表就会显示到屏幕上了。

3.3 总结

到此,我们终于将Android系统启动流程这一主题分析完毕,结合前面的几篇内容,可以得出核心流程如下:

  • 1、启动电源以及系统启动:当电源按下时引导芯片从预定义的订房(固化在ROM)开始执行,加载引导程序BootLoader到RAM,然后执行。
  • 2、引导程序BootLoader:BootLoader是在Android系统开始运行前的一个小程序,主要用于把系统OS拉起来并运行。。
  • 3、Linux内核启动:当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当其完成系统设置时,会先在系统文件中寻找init.rc文件,并启动init进行。
  • 4、init进程启动:初始化和启动属性服务,并且启动Zygote进程。
  • 5、Zygote进程启动:创建JVM并为其注册JNI方法,创建服务器端Socket,启动SystemServer进程。
  • 6、SystemServer进程启动:启动Binder线程池和SystemServiceManager,并且启动各种系统服务。
  • 7、Launcher启动:被SystemServer进程启动的AMS会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到系统桌面上。