【Android】框架层学习笔记——系统启动流程

【Android】框架层学习笔记——系统启动流程

Android框架层学习笔记——系统启动流程

首先要感谢@刘望舒大神的博客,让我们这些渣渣有途径更快速地接触到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;并且拥有用户组1001~1010,1018、1021、1032、3001~3010的权限;进程名为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的频率、使用时常
WebViewUpdateService WebView更新服务
其他服务 作用
CameraService 摄像头相关服务
AlarmManagerService 全局定时器管理服务
InputManagerService 管理输入事件
WindowManagerService 窗口管理服务
VrManagerService VR模式管理服务
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启动后会将已安装应用的快捷图标显示到界面上。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: