Android学习笔记——Android系统的启动流程(三个进程以及Launcher)

首先要感谢**@刘望舒**大神的博客,让我们这些渣渣有途径更快速地接触到Android框架层的内容。

本篇博客主要基于Android7.0来分析Android系统的启动流程。

init进程启动过程

init进程

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

作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等等。i由多个源文件共同组成,这些文件位于源码目录system/core/init。

启动前几步

我们首先需要了解系统启动流程的前几步。

1. 电源及系统的启动

当电源按下时,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。

2. 引导程序Bootloader

引导程序是Android系统开始运行前的一个小程序,它可以把系统OS拉起并运行。

3. Linux内核启动

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

4. 启动init进程

第四步就是开始启动我们此处讲到的init进程了。

init入口函数

init进程的入口函数为main函数,使用C++编写。位于system/core/init/init.cpp

int main(int argc, char** argv) {
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }
    if (!strcmp(basename(argv[0]), "watchdogd")) {
        return watchdogd_main(argc, argv);
    }
    umask(0);
    add_environment("PATH", _PATH_DEFPATH);
    bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
    //创建文件并挂载
    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);
    }
    open_devnull_stdio();
    klog_init();
    klog_set_level(KLOG_NOTICE_LEVEL);
    NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
    if (!is_first_stage) {
        // Indicate that booting is in progress to background fw loaders, etc.
        close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
        //初始化属性相关资源
        property_init();//1
        process_kernel_dt();
        process_kernel_cmdline();
        export_kernel_boot_props();
    }
 ...
    //启动属性服务
    start_property_service();//2
    const BuiltinFunctionMap function_map;
    Action::set_function_map(&function_map);
    Parser& parser = Parser::GetInstance();
    parser.AddSectionParser("service",std::make_unique<ServiceParser>());
    parser.AddSectionParser("on", std::make_unique<ActionParser>());
    parser.AddSectionParser("import", std::make_unique<ImportParser>());
    //解析init.rc配置文件
    parser.ParseConfig("/init.rc");//3
   ...   
       while (true) {
        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) {
            ((void (*)()) ev.data.ptr)();
        }
    }
    return 0;
}

main方法中做了很多事情,我们需要关注的是下面几点:

  • 注释1处调用property_init函数对属性初始化
  • 注释2处调用start_property_service()函数启动属性服务
  • 注释3处调用parser.ParseConfig(“/init.rc”)解析 init.rc 文件。(解析init.rc的源文件位于system/core/init/init_parse.cpp)

接下来我们看看 init.rc 中做了什么

init.rc

init.rc是一个配置文件,是由Android初始化语言(Android Init Language)编写的脚本,主要包含Action、Commands、Services、Options和Import这五种类型的语句。

init.rc位于system/core/rootdir/init.rc

on init
    sysclktz 0
    # Mix device-specific information into the entropy pool
    copy /proc/cmdline /dev/urandom
    copy /default.prop /dev/urandom
...

on boot
    # basic network init
    ifup lo
    hostname localhost
    domainname localdomain
    # set RLIMIT_NICE to allow priorities from 19 to -20
    setrlimit 13 40 40
...    

其中 on init 和 on boot 是Action类型的语句,格式为

on <trigger> [&& <trigger>]*     //设置触发器  
   <command>  
   <command>      //动作触发之后要执行的命令  

为了分析如何创建zygote,我们需要查看Services类型语句,它的格式如下:

service <name> <pathname> [ <argument> ]*   //<service的名字><执行程序路径><传递参数>  
   <option>       //option是service的修饰词,影响什么时候、如何启动services  
   <option>  
   ...  

在Android 7.0中对init.rc文件进行了拆分,每个服务一个rc文件。

我们要分析的zygote服务的启动脚本在init.zygoteXX.rc中定义。以拿64位处理器为例,init.zygote64.rc的代码如下所示。

init.zygoteXX.rc位于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

service用于通知init进程创建名zygote的进程,zygote进程执行程序的路径为/system/bin/app_process64,后面的则是要传给app_process64的参数。class main指的是zygote的class name为main。

解析service

接下来我们解析service,它会用到两个函数:

ParseSection函数用于解析service的rc文件,如init.zygoteXX.rc。

ParseSection函数主要用来搭建service的架子。另一个是ParseLineSection,用于解析子项。

service位于system/core/init/service.cpp

bool ServiceParser::ParseSection(const std::vector<std::string>& args,
                                 std::string* err) {
    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());
    service_ = std::make_unique<Service>(name, "default", str_args);//1
    return true;
}

bool ServiceParser::ParseLineSection(const std::vector<std::string>& args,
                                     const std::string& filename, int line,
                                     std::string* err) const {
    return service_ ? service_->HandleLine(args, err) : false;
}

在注释1中,通过参数构建了一个Service对象,它的 classname 为 “default”。

解析完毕后悔调用EndSection方法:

void ServiceParser::EndSection() {
    if (service_) {
        ServiceManager::GetInstance().AddService(std::move(service_));
    }
}

可以看到,这里调用了ServiceManager这个单例类的AddService方法。我们现在看看AddService方法做了什么:

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处是将Service对象加入到services这个链表中。

上面的解析过程总的来讲,就是根据参数创建Service对象,根据选项域的内容填充Service对象,最后将其加入到vector类型的services链表中。

init启动zygote

分析完service后,我们来了解init如何启动service。我们在这里主要了解启动zygote这个service。我们在之前的脚本中看到了zygote的classname为main,在init.rc中有如下的配置代码:

init.rc位于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是 Commend类型,对应的函数为do_class_start。我们知道main指的就是zygote,因此class_start main用于启动zygote。do_class_start函数在builtins.cpp中定义。

builtins位于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::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
    return 0;
}

可以看到这里在ServiceManager中寻找到了对应Service,之后调用了Service的StartIfNotDisabled函数。

我们看到StartIfNotDisabled函数.

StartIfNotDisabled 位于 system/core/init/service.cpp

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

当Service不是DISABLED时,便会调用它的Start函数

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

...
    pid_t pid = fork();//1.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执行程序
        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;
}

看到注释1和2的代码,在Start方法中用fork函数创建了子进程,并且在子进程中调用了execve函数来执行system/bin/app_process。这样就进入了framework/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);//1
    } 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。

属性服务

Windows上有一个注册表管理器,注册表采用键值对的方式记录用户、软件的一些使用信息。即使系统重启,仍能根据之前在注册表的记录进行相应的初始化操作。

Android系统中也有一个类似的机制,就是此处的属性服务

我们在前文中提到了,在init.cpp的代码中有和属性服务有关的代码。

system/core/init/init.cpp

property_init();
start_property_service();

这两句代码进行了属性服务的配置及属性服务的启动。我们来了解服务配置的初始化及启动。

属性服务的初始化及启动

property_init函数具体实现如下

system/core/init/property_service.cpp

void property_init() {
    if (__system_property_area_init()) {
        ERROR("Failed to initialize property area\n");
        exit(1);
    }
}

其中__system_property_area_init函数用于初始化属性的内存区域,接下来看到start_property_service函数

void start_property_service() {
    property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0666, 0, 0, NULL);//1
    if (property_set_fd == -1) {
        ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
        exit(1);
    }
    listen(property_set_fd, 8);//2
    register_epoll_handler(property_set_fd, handle_property_set_fd);//3
}

注释1创建了一个非阻塞的Socket,注释2处调用了listen函数对这个socket进行监听。这样创建的Socket就成为了Server,也就是属性服务。

listen函数的第二个参数8意味着属性服务最多可以同时为8个试图设置属性的用户提供服务。

注释3将这个Socket放入了epoll句柄中,用epoll来监听property_set_fd。当Socket中有数据到来时,init进程将用handle_property_set_fd函数进行处理。

属性服务处理请求

当属性服务收到客户端的请求便会调用handle_property_set_fd函数进行处理,我们看它的实现

system/core/init/property_service.cpp

static void handle_property_set_fd()
{  
...

        if(memcmp(msg.name,"ctl.",4) == 0) {
            close(s);
            if (check_control_mac_perms(msg.value, source_ctx, &cr)) {
                handle_control_message((char*) msg.name + 4, (char*) msg.value);
            } else {
                ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d\n",
                        msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);
            }
        } else {
            //检查客户端进程权限
            if (check_mac_perms(msg.name, source_ctx, &cr)) {//1
                property_set((char*) msg.name, (char*) msg.value);//2
            } else {
                ERROR("sys_prop: permission denied uid:%d  name:%s\n",
                      cr.uid, msg.name);
            }
            close(s);
        }
        freecon(source_ctx);
        break;
    default:
        close(s);
        break;
    }
}

在注释1处,检查了客户端的进程权限,注释2处则调用property_set函数进行属性的修改

int property_set(const char* name, const char* value) {
    int rc = property_set_impl(name, value);
    if (rc == -1) {
        ERROR("property_set(\"%s\", \"%s\") failed\n", name, value);
    }
    return rc;
}

property_set实际是调用property_set_impl函数来实现具体功能

static int property_set_impl(const char* name, const char* value) {
    size_t namelen = strlen(name);
    size_t valuelen = strlen(value);
    if (!is_legal_property_name(name, namelen)) return -1;
    if (valuelen >= PROP_VALUE_MAX) return -1;
    if (strcmp("selinux.reload_policy", name) == 0 && strcmp("1", value) == 0) {
        if (selinux_reload_policy() != 0) {
            ERROR("Failed to reload policy\n");
        }
    } else if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) {
        if (restorecon_recursive(value) != 0) {
            ERROR("Failed to restorecon_recursive %s\n", value);
        }
    }
    //从属性存储空间查找该属性
    prop_info* pi = (prop_info*) __system_property_find(name);
    //如果属性存在
    if(pi != 0) {
       //如果属性以"ro."开头,则表示是只读,不能修改,直接返回
        if(!strncmp(name, "ro.", 3)) return -1;
       //更新属性值
        __system_property_update(pi, value, valuelen);
    } else {
       //如果属性不存在则添加该属性
        int rc = __system_property_add(name, namelen, value, valuelen);
        if (rc < 0) {
            return rc;
        }
    }
    /* If name starts with "net." treat as a DNS property. */
    if (strncmp("net.", name, strlen("net.")) == 0)  {
        if (strcmp("net.change", name) == 0) {
            return 0;
        }
      //以net.开头的属性名称更新后,需要将属性名称写入net.change中  
        property_set("net.change", name);
    } else if (persistent_properties_loaded &&
            strncmp("persist.", name, strlen("persist.")) == 0) {
        /*
         * Don't write properties to disk until after we have read all default properties
         * to prevent them from being overwritten by default values.
         */
        write_persistent_property(name, value);
    }
    property_changed(name, value);
    return 0;
}

property_set_impl函数主要用来对属性进行修改,并且对以ro、net和persist开头的属性分别进行不同的处理。

init进程启动的总结

init进程主要做了三件事:
1.创建一些文件夹并挂载设备
2.初始化和启动属性服务
3.解析init.rc配置文件并启动zygote进程

Zygote进程启动过程

前面我们了解到在init进程中启动了zygote进程,那么zygote进程又做了什么操作呢?

Zygote进程

在Android中,Dalvik、应用程序进程及运行系统的关键服务的SystemServer进程均是由Zygote进程来创建,因此我们称Zygote线程为孵化器它通过 fork(复制进程)的形式创建应用程序进程和 SystemServer 进程。由于Zygote启动时创建了Dalvik,因此通过fork创建的应用程序进程和SystemServer进程可以在内部获取一个Dalvik的实例拷贝。

Init进程通过AppRuntime启动Zygote进程

从前文可以知道init启动zygote是调用app_main.cpp的main中AppRuntimestart方法来启动zygote进程。我们从app_main.cpp的main开始分析

frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
...

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
   ...
     Vector<String8> args;
    if (!className.isEmpty()) {
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);
    } else {
        // We're in zygote mode.
        maybeCreateDalvikCache();
        if (startSystemServer) {
            args.add(String8("start-system-server"));//1
        }
        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);
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string());
        set_process_name(niceName.string());
    }
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//2
    } 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处,如果startSystemServer为true(默认),会将”start-system-server”放入启动参数args。

注释2处调用runtime的start函数来启动zygote进程,并将args传入。这样启动zygote进程后,zygote进程会将SystemServer进程启动。

我们知道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) {//1
        return;
    }
    onVmCreated(env);
    if (startReg(env) < 0) {//2
        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);
    }
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
    //找到ZygoteInit的main函数
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");//3
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
        //通过JNI调用ZygoteInit的main函数
            env->CallStaticVoidMethod(startClass, startMeth, strArray);//4

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
  ...
}

注释1处调用startVm函数来创建JavaVm(Dalvik)

注释2处调用startReg函数用来为DVM注册JNI。

注释3处的代码用来找到ZygoteInit的main函数,其中startClass从app_main的main函数得知为com.android.internal.os.ZygoteInit。

注释4处通过JNI调用ZygoteInit的main函数,因为ZygoteInit的main函数是Java编写的,因此需要通过JNI调用。

Zygote的Java框架层

前文中我们在AndroidRuntime的start方法中通过JNI调用了ZygoteInitmain函数,之后Zygote便进入了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
           ...
            if (startSystemServer) {
            //启动SystemServer进程
                startSystemServer(abiList, socketName);//3
            }
            Log.i(TAG, "Accepting command socket connections");
            //等待客户端请求
            runSelectLoop(abiList);//4
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

注释1通过registerZygoteSocket方法创建Server端的Socket。这个名为zygote的Socket用于等ActivityManagerService请求Zygote创建新的应用程序进程。

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

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

注释4处调用runSelectLoop函数来等待客户端请求。

由此得知,ZygoteInit的main函数主要做了4件事

接下来我们对主要的事件一一进行分析。

registerZygoteSocket

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);//1
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
       }
}

注释1处用来创建LocalServerSocket,也就是服务端的Socket。当Zygote进程将SystemServer进程启动后,就会在这个服务端的Socket上来等待ActivityManagerService请求Zygote进程来创建新的应用程序进程。

启动SystemServer进程

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
...
        /* Hardcoded command line to start the system server */
         /*1*/
        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);//2
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /*3*/
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);//4
        }

        return true;
    }
}    

注释1用来创建args数组,这个数组用来保存启动SystemServer的启动参数。

可以看出SystemServer进程的用户id和用户组id被设置为1000;并且拥有用户组10011010,1018、1021、1032、30013010的权限;进程名为system_server;启动的类名为com.android.server.SystemServer。

注释2处将args封装成Arguments对象供注释3的 forkSystemServer 函数调用

注释3处调用Zygote的forkSystemServer,主要通过fork函数在当前进程创建一个子进程,如果返回的pid 为0,也就是表示在新创建的子进程中执行的,则执行注释4处的handleSystemServerProcess来启动SystemServer进程。

runSelectLoop

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        fds.add(sServerSocket.getFileDescriptor());//1
        peers.add(null);

        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {//2
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {//3
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);//4
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce();//5
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

注释1处中的sServerSocket就是我们在registerZygoteSocket函数中创建的服务端Socket,调用sServerSocket.getFileDescriptor()获得该Socket的fd字段的值并添加到fd列表fds中。之后无限循环用来等待ActivityManagerService请求Zygote进程创建新的应用程序进程。

注释2处通过遍历将fds存储的信息转移到pollFds数组中。

在注释3处对pollFds进行遍历,如果i==0则说明服务端Socket与客户端连接上,也就是当前Zygote进程与ActivityManagerService建立了连接。

注释4处通过acceptCommandPeer函数得到ZygoteConnection类并添加到Socket连接列表peers中。接着将该ZygoteConnection的fd添加到fd列表fds中,以便可以接收到ActivityManagerService发送过来的请求。如果i的值大于0,则说明ActivityManagerService向Zygote进程发送了一个创建应用进程的请求。

之后则在注释5处调用ZygoteConnection的runOnce函数来创建一个新的应用程序进程。并在成功创建后将这个连接从Socket连接列表peers和fd列表fds中清除。

Zygote进程的总结

Zygote进程主要进行了下面的几个操作:

  1. 创建AppRuntime并且调用它的start方法,启动Zygote进程
  2. 创建DVM并为DVM注册JNI
  3. 通过JNI调用ZygoteInit中的main函数从而进入Java框架层
  4. 通过registerZygoteSocket创建服务端Socket,通过runSelectLoop函数等待ActivityManagerService的创建应用进程的请求。
  5. 启动SystemServer进程。

SystemServer进程启动过程

Zygote进程启动SystemServer进程

前面提到Zygote进程中通过ZygoteInit.java中的startSystemServer方法启动了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;
}

在startSystemServer函数中调用handleSystemServerProcess来启动SyetemServer进程。

SyetemServer进程启动过程

handleSystemServerProcess的代码如下

 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对SystemServer来没有意义,因此在注释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线程池

接下来我们看nativeZygoteInit方法对应的JNI文件,如下:

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文件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中定义。我们看到AppRuntime中的onZygoteInit函数。

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.javanativeZygoteInit函数主要做的就是启动Binder线程池。

invokeStaticMain

我们回到RuntimeInit.java,它在注释2调用了applicationInit方法

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

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

里面调用了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”,通过反射,可以获取到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函数被动态调用。

SystemServer进程分析

我们先来查看SystemServer的main函数:

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

 public static void main(String[] args) {
        new SystemServer().run();
 }

此处调用了创建了SystemServer并调用了其run方法。

private void run() {
        ...
            System.loadLibrary("android_servers");//1
        ...
            mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        ...    
         try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();//3
            startCoreServices();//4
            startOtherServices();//5
        } 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处创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。启动系统的各种服务。

注释3中的startBootstrapServices方法中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。

注释4处的startBootstrapServices方法中则启动了BatteryService、UsageStatsService和WebViewUpdateService。

注释5处的startOtherServices方法中则启动了CameraService、AlarmManagerService、VrManagerService等服务

这些服务的父类为SystemService。从注释3、4、5的函数可以看出,官方把系统服务分为了三种类型,分别是引导服务核心服务其他服务,其中其他服务为一些非紧要和一些不需要立即启动的服务。系统服务大约有80多个,这里列出部分系统服务以及它们的作用如下表所示:

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

比如要启动PowerManagerService则会调用如下代码:

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

SystemServiceManager的startService函数启动了PowerManagerService,startService函数如下所示。

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

SystemServer进程的总结

SystemServer进程启动时做了如下工作:

  1. 调用Native方法启动Binder线程池,这样就能与其他进程通信
  2. 创建SystemServiceManager,用于对系统的服务进行创建、启动和生命周期管理。
  3. 启动各种系统服务(引导服务、核心服务、其他服务)

Launcher启动过程与系统的启动流程

前面我们介绍了Init进程、Zygote进程、SystemServer进程的启动流程,下面我们介绍系统启动的最后一步——Launcher的启动过程。

Launcher

Android系统的启动的最后一步是启动一个Home应用程序,用于显示我们已经安装的各类应用程序。这个Home应用程序就是我们所说的Launcher。在启动Launcher时会请求PackageManagerService返回系统中已经安装的应用程序的信息,并且将这些信息封装为快捷图标列表显示在屏幕上,便于用户点击来启动相应应用程序。

Launcher的启动流程

SystemServer启动的时候会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。而在此之前启动的ActivityManagerService则会将Launcher启动起来。

启动Launcher的入口函数为ActivityManagerService的systemReady方法:

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

...
}
...
}

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/ActivityStackSupervisor.java

boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
    ...
    if (r != null && !r.finishing) {
        mService.setFocusedActivityLocked(r, myReason);
        return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
    }
    return mService.startHomeActivityLocked(mCurrentUser, myReason);//1
}

在注释1处调用了ActivityManagerService的startHomeActivityLocked方法,如下:

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的Manifest文件如下所示。

packages/apps/Launcher3/AndroidManifest.xml

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.launcher3">
    <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="16"/>
 ...
 <application
        ...
        <activity
            android:name="com.android.launcher3.Launcher"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:theme="@style/Theme"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="nosensor"
            android:configChanges="keyboard|keyboardHidden|navigation"
            android:resumeWhilePausing="true"
            android:taskAffinity=""
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY"/>
            </intent-filter>
        </activity>
...
  </application> 
</manifest>

这样,应用程序Launcher就会被启动,并执行它的onCreate方法。

Launcher应用图标的显示流程

我们可以看到Launcher应用的onCreate方法

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       ...
        LauncherAppState app = LauncherAppState.getInstance();//1
        mDeviceProfile = getResources().getConfiguration().orientation
                == Configuration.ORIENTATION_LANDSCAPE ?
                app.getInvariantDeviceProfile().landscapeProfile
                : app.getInvariantDeviceProfile().portraitProfile;

        mSharedPrefs = Utilities.getPrefs(this);
        mIsSafeModeEnabled = getPackageManager().isSafeMode();
        mModel = app.setLauncher(this);//2
        ....
        if (!mRestoring) {
            if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {
                mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);//2
            } else {
                mModel.startLoader(mWorkspace.getRestorePage());
            }
        }
		...
    }

注释1处获取了LauncherAppState的实例

注释2处调用了LauncherAppState的setLauncher方法,传入这个Launcher对象。

我们看到setLauncher方法

packages/apps/Launcher3/src/com/android/launcher3/LauncherAppState.java

LauncherModel setLauncher(Launcher launcher) {
     getLauncherProvider().setLauncherProviderChangeListener(launcher);
     mModel.initialize(launcher);//1
     mAccessibilityDelegate = ((launcher != null) && Utilities.ATLEAST_LOLLIPOP) ?
         new LauncherAccessibilityDelegate(launcher) : null;
     return mModel;
}

它在注释1处会调用LauncherMode的initalize方法。

public void initialize(Callbacks callbacks) {
    synchronized (mLock) {
        unbindItemInfosAndClearQueuedBindRunnables();
        mCallbacks = new WeakReference<Callbacks>(callbacks);
    }
}

在initalize方法中会将Callbacks,也就是传入的Launcher 封装成一个弱引用对象。因此我们得知mCallbacks变量指的就是封装成弱引用对象的Launcher。

我们再回到Launcher的onCreate函数,在注释2处调用了LauncherModel的startLoader函数:

...
 @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");//1
    static {
        sWorkerThread.start();
    }
    @Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper());//2
...
   public void startLoader(int synchronousBindPage, int loadFlags) {s
        InstallShortcutReceiver.enableInstallQueue();
        synchronized (mLock) {
            synchronized (mDeferredBindRunnables) {
                mDeferredBindRunnables.clear();
            }
            if (mCallbacks != null && mCallbacks.get() != null) {
                stopLoaderLocked();
                mLoaderTask = new LoaderTask(mApp.getContext(), loadFlags);//3
                if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
                        && mAllAppsLoaded && mWorkspaceLoaded && !mIsLoaderTaskRunning) {
                    mLoaderTask.runBindSynchronousPage(synchronousBindPage);
                } else {
                    sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                    sWorker.post(mLoaderTask);//4
                }
            }
        }
    }

注释1创建了具有消息循环的线程HandlerThread对象。

注释2处创建了Handler,并且传入HandlerThread的Looper。

注释3处创建LoaderTask,在注释4处将LoaderTask作为消息发送给HandlerThread 。

LoaderTask类实现了Runnable接口,当LoaderTask所描述的消息被处理时则会调用它的run函数

private class LoaderTask implements Runnable {
...
       public void run() {
           synchronized (mLock) {
               if (mStopped) {
                   return;
               }
               mIsLoaderTaskRunning = true;
           }
           keep_running: {
               if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");
               loadAndBindWorkspace();//1
               if (mStopped) {
                   break keep_running;
               }
               waitForIdle();
               if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");
               loadAndBindAllApps();//2
           }
           mContext = null;
           synchronized (mLock) {
               if (mLoaderTask == this) {
                   mLoaderTask = null;
               }
               mIsLoaderTaskRunning = false;
               mHasLoaderCompletedOnce = true;
           }
       }
  ...     
 }

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

注释1处调用loadAndBindWorkspace方法用来加载工作区信息

注释2处的loadAndBindAllApps方法是用来加载系统已经安装的应用程序信息。

private void loadAndBindAllApps() {
    if (DEBUG_LOADERS) {
        Log.d(TAG, "loadAndBindAllApps mAllAppsLoaded=" + mAllAppsLoaded);
    }
    if (!mAllAppsLoaded) {
        loadAllApps();//1
        synchronized (LoaderTask.this) {
            if (mStopped) {
                return;
            }
        }
        updateIconCache();
        synchronized (LoaderTask.this) {
            if (mStopped) {
                return;
            }
            mAllAppsLoaded = true;
        }
    } else {
        onlyBindAllApps();
    }
}

如果系统没有加载已经安装的应用程序信息,则会调用注释1处的loadAllApps函数:

  private void loadAllApps() {
...
        mHandler.post(new Runnable() {
            public void run() {
                final long bindTime = SystemClock.uptimeMillis();
                final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                if (callbacks != null) {
                    callbacks.bindAllApplications(added);//1
                    if (DEBUG_LOADERS) {
                        Log.d(TAG, "bound " + added.size() + " apps in "
                                + (SystemClock.uptimeMillis() - bindTime) + "ms");
                    }
                } else {
                    Log.i(TAG, "not binding apps: no Launcher activity");
                }
            }
        });
       ...
    }

在注释1处调用了callbacks的bindAllApplications方法。我们知道,callback就是之前传入的Launcher。我们可以查看Launcher的bindAllApplications方法

public void bindAllApplications(final ArrayList<AppInfo> apps) {
    if (waitUntilResume(mBindAllApplicationsRunnable, true)) {
        mTmpAppsList = apps;
        return;
    }
    if (mAppsView != null) {
        mAppsView.setApps(apps);//1
    }
    if (mLauncherCallbacks != null) {
        mLauncherCallbacks.bindAllApplications(apps);
    }
}

注释1处调用了AllAppsContainerView的setApps函数,并将包含应用信息的列表apps传进去。

packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java

public void setApps(List<AppInfo> apps) {
      mApps.setApps(apps);
}

包含应用信息的列表apps已经传给了AllAppsContainerView,查看AllAppsContainerView的onFinishInflate函数:

@Override
protected void onFinishInflate() {
    super.onFinishInflate()
    ...
    // Load the all apps recycler view
    mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);//1
    mAppsRecyclerView.setApps(mApps);//2
    mAppsRecyclerView.setLayoutManager(mLayoutManager);
    mAppsRecyclerView.setAdapter(mAdapter);//3
    mAppsRecyclerView.setHasFixedSize(true);
    mAppsRecyclerView.addOnScrollListener(mElevationController);
    mAppsRecyclerView.setElevationController(mElevationController)
    ...
}

onFinishInflate函数在加载完xml文件时就会调用

注释1处得到AllAppsRecyclerView用来显示App列表。

注释2处将apps的信息列表传进去。

注释3处为AllAppsRecyclerView设置Adapter。

这样,就成功的将应用程序的快捷方式显示在了屏幕上

Android启动流程总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值