这篇文章只是对刘望舒大佬书籍的摘抄,适合复习用,没看过的请先看大佬的原书
下面是大佬博客的链接
Android进阶三部曲 第二部《Android进阶解密》
Android系统的启动流程有以下几个部分
启动电源以及系统启动
当电源按下时,引导芯片从预定义的地方(固化在ROM)开始执行。加载引导程序(BootLoader)到RAM,然后执行
引导程序BootLoader
引导程序BootLoader是在Android操作系统开始运行前的一个小程序,主要作用是把系统OS(Linux系统?)拉起来并运行
Linux内核启动
当Linux内核启动时,先进行系统设置(设置缓存、被保护存储器、计划列表、加载驱动)。当内核完成系统设置时,它首先在系统文件中寻找init.rc文件,并启动init进程。
Init进程启动
init进程会初始化和启动属性服务,并且启动Zygote进程
Zygote进程启动
Zygote进程会创建Java虚拟机并为Java虚拟机注册JNI方法,创建服务端Socket,启动SystemService进程。
SystemService进程启动
SystemService进程会启动Binder线程池和SystemServiceManager,并且启动各种系统服务,包括AMS进程
Launcher启动
AMS进程会启动Launcher,Launcher启动后会将已安装的快捷图标显示在界面上
Android系统流程图如下

init进程是Android系统中用户空间的第一个进程。它主要做三件事
下面为init进程的入口函数main
int main(int argc, char** argv) {
...
add_environment("PATH", _PATH_DEFPATH);
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
if (is_first_stage) {
boot_clock::time_point start_time = boot_clock::now();
// 清理umask
umask(0);
// 创建和挂载启动动所需的文件目录
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
// 不要将原始命令行暴露给非特权进程。
chmod("/proc/cmdline", 0440);
gid_t groups[] = { AID_READPROC };
setgroups(arraysize(groups), groups);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
//初始化Kernel的log,这样就可以从外界获取Kernel的日志
InitKernelLogging(argv);
...
}
...
//初始化属性服务
property_init();
...
//创建epoll句柄,epoll_fd声明为类的static int
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
PLOG(ERROR) << "epoll_create1 failed";
exit(1);
}
//设置子进程信号处理器,如果子进程异常退出,init进程会调用该函数中设定的信号处理函数进行处理
signal_handler_init();//1
//导入默认的环境变量
property_load_boot_defaults();
export_oem_lock_status();
//启动属性服务
start_property_service();
set_usb_controller();
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);
//获取parse对象
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>());
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
//解析int.rc配置文件//2
parser.ParseConfig("/init.rc");
parser.set_is_system_etc_init_loaded(
parser.ParseConfig("/system/etc/init"));
parser.set_is_vendor_etc_init_loaded(
parser.ParseConfig("/vendor/etc/init"));
parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
} else {
parser.ParseConfig(bootscript);
parser.set_is_system_etc_init_loaded(true);
parser.set_is_vendor_etc_init_loaded(true);
parser.set_is_odm_etc_init_loaded(true);
}
if (false) parser.DumpState();
ActionManager& am = ActionManager::GetInstance();
...
while (true) {
// 默认情况下,睡眠直到发生某些事情。
int epoll_timeout_ms = -1;
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
//内部遍历执行每个action中携带的command队形的执行函数
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
//重启死去的进程
restart_processes();
// 如果有需要重新启动的进程,请及时唤醒。
if (process_needs_restart_at != 0) {
epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
}
// 如果还有更多工作要做,请立即再次醒来。
if (am.HasMoreCommands()) epoll_timeout_ms = 0;
}
epoll_event ev;
//此处等待
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
if (nr == -1) {
PLOG(ERROR) << "epoll_wait failed";
} else if (nr == 1) {
((void (*)()) ev.data.ptr)();
}
}
return 0;
}
init的main函数在开始的时候创建和挂载启动所需的文件目录,其中挂载了tmpfs、devpts、proc、sysfs、selinuxfs共5种文件系统
注释1处设置设置子进程信号处理函数,主要是防止int进程的子进程成为僵尸进程,占用系统进程表这种有限资源,导致系统错误
注释2处进行解析int.rc文件
Init.rc文件是一个由Android初始化语言编写的脚本。
Android初始化语言主要包含5种类型语句:Action、Command、Service、Option和Import。
Action类型语句格式如下
on <trigger> [&&<trigger>]* //设置触发器 <command> <command> //动作触发后要执行的命令
- 1
- 2
- 3
Service类型语句格式如下
service <name> <pathname> [<argument>]* //<service的名字><执行程序路径><传递参数> <option> //option是service的修饰词,影响什么时候,如何启动service <option> ...
- 1
- 2
- 3
- 4
在Android8.0中对init.rc文件进行了拆分,每个服务对应一个rc文件,Zygote的启动脚本在init.zygoteXX.rc,中,64位处理器为init.zygote64.rc,代码如下
/system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
第一行表示 Service 用于通知 init 进程创建名为zygote的进程,这个进程执行程序的路径为 /system/bin/app_process64 后面为传给进程的参数
class main 表示zygote 这个Service的classname为main。
init.rc中的各种类型语句都相应的类来解析,Action类型语句采用ActionParser来解析,Service类型语句采用ServiceParse来进行解析。ServiceParse的实现代码在system/core/init/service.cpp中,主要是ServiceParser::ParseSection函数和ServiceParser::ParseLineSection函数
on nonencrypted
class_start main //1
class_start late_start
init.rc中有如上代码
class_start是一个COMMAND,对应的函数为do_class_start。注释1处表示启动classname 为 main 的 Service。从上面我们知道Zygote 的classname 就是 main,也就是说上面就是在启动Zygote的。而class_start命令对应的函数是do_class_start
/system/core/init/builtins.cpp
static int do_class_start(const std::vector<std::string>& args) {
//启动一个类不会启动明确禁用的服务。 它们必须单独启动。
ServiceManager::GetInstance().
ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
return 0;
}
ForEachServiceInClass函数会遍历Service链表,找到classname为main的Zygote,并执行StartIfNotDisabled
bool Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) {
//如果没有设置disable选项,则调用Start()
return Start();
} else {
flags_ |= SVC_DISABLED_START;
}
return true;
}
由于init.rc6文件中没有设置disable选项所以会调用Start方法
bool Service::Start() {
// 启动服务会将其从禁用或重置状态中移除,并立即将其从重新启动状态中移除(如果它在那里)。
flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
// 如果Service正在运行,则不启动
if (flags_ & SVC_RUNNING) {
return false;
}
...
//判断需要启动的Service的对应文件是否存在,不存在则不启动该Service
struct stat sb;
if (stat(args_[0].c_str(), &sb) == -1) {
flags_ |= SVC_DISABLED;
return false;
}
...
pid_t pid = -1;
if (namespace_flags_) {
pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
} else {
//如果子进程没有启动,则调用fork函数创建子进程
pid = fork();
}
if (pid == 0) {
//如果运行在子进程中
umask(077);
...
std::vector<char*> strs;
ExpandArgs(args_, &strs);
//调用execve函数,Service子进程就会被启动
if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
}
_exit(127);
}
...
return true;
}
调用execve函数Service 子进程会被启动,并进入该Service的main函数,而Service 是Zygote时,对应的程序路径为/system/bin/app_process,对应的文件为app_main.cpp,这样就会进入到了app_main.cpp的main函数中
/frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
...
bool zygote = false;
...
while (i < argc) {
//解析启动的参数
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
//如果包含--zygote则是在启动zygote进程
zygote = true;
niceName = ZYGOTE_NICE_NAME;
}
...
}
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
...
}
此处调用runtime的start函数启动Zygote
Windows平台上有一个注册表管理器,其内容采用键值对的形式来记录用户、软件的一些使用信息。及时系统或软件重启也可以根据之前注册表的记录,进行响应的初始化。Android的属性服务也会是类似
init进程启动时会启动属性服务,并为其分配内存,用来存储这些属性。如果需要这些属性可以直接读取
int main(int argc, char** argv) {
...
//初始化属性服务
property_init();
...
//启动属性服务
start_property_service();
...
}
首先看property_init函数
/system/core/init/property_service.cpp
void property_init() {
//初始化属性内存区域
if (__system_property_area_init()) {
LOG(ERROR) << "Failed to initialize property area";
exit(1);
}
}
再看start_property_service
void start_property_service() {
property_set("ro.property_service.version", "2");
//创建非阻塞式的Socket
property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
0666, 0, 0, NULL);
if (property_set_fd == -1) {
PLOG(ERROR) << "start_property_service socket creation failed";
exit(1);
}
//对property_set_fd监听,listen函数的第二个参数表示最对可以同时为8个用户提供设置属性的五福
listen(property_set_fd, 8);
//将property_set_fd放入epoll中,用epoll来监听property_set_fd,当property_set_fd有数据时,调用handle_property_set_fd函数进行处理
register_epoll_handler(property_set_fd, handle_property_set_fd);
}
接下来看handle_property_set_fd函数
static void handle_property_set_fd() {
...
switch (cmd) {
case PROP_MSG_SETPROP: {
char prop_name[PROP_NAME_MAX];
char prop_value[PROP_VALUE_MAX];
//如果Socket去读不到属性数据则返回
if (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) ||
!socket.RecvChars(prop_value, PROP_VALUE_MAX, &timeout_ms)) {
PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket";
return;
}
prop_name[PROP_NAME_MAX-1] = 0;
prop_value[PROP_VALUE_MAX-1] = 0;
//在handle_property_set处理
handle_property_set(socket, prop_value, prop_value, true);
break;
}
...
}
}
static void handle_property_set(SocketConnection& socket,
const std::string& name,
const std::string& value,
bool legacy_protocol) {
...
//如果属性明晨以"ctl."开头,说明是控制属性
if (android::base::StartsWith(name, "ctl.")) {
//检查客户端权限
if (check_control_mac_perms(value.c_str(), source_ctx, &cr)) {
//设置控制属性,控制属性用来执行一些命令,比如开机动画
handle_control_message(name.c_str() + 4, value.c_str());
if (!legacy_protocol) {
socket.SendUint32(PROP_SUCCESS);
}
} else {
...
}
} else {
//普通属性走这里
//检查客户端权限
if (check_mac_perms(name, source_ctx, &cr)) {
//修改普通属性
uint32_t result = property_set(name, value);
if (!legacy_protocol) {
socket.SendUint32(result);
}
} else {
...
}
}
freecon(source_ctx);
}
uint32_t property_set(const std::string& name, const std::string& value) {
size_t valuelen = value.size();
//判断属性是否合法
if (!is_legal_property_name(name)) {
LOG(ERROR) << "property_set(\"" << name << "\", \"" << value << "\") failed: bad name";
return PROP_ERROR_INVALID_NAME;
}
...
从属性存储空间查找属性
prop_info* pi = (prop_info*) __system_property_find(name.c_str());
//如果属性存在
if (pi != nullptr) {
// 如果属性名称以"ro."开头,表示只读,不能修改,直接返回
if (android::base::StartsWith(name, "ro.")) {
LOG(ERROR) << "property_set(\"" << name << "\", \"" << value << "\") failed: "
<< "property already set";
return PROP_ERROR_READ_ONLY_PROPERTY;
}
//更新属性值
__system_property_update(pi, value.c_str(), valuelen);
} else {
// 如果属性不存在,添加该属性
int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
if (rc < 0) {
LOG(ERROR) << "property_set(\"" << name << "\", \"" << value << "\") failed: "
<< "__system_property_add failed";
return PROP_ERROR_SET_FAILED;
}
}
//如果属性以"persist."开头,表示持久化属性
if (persistent_properties_loaded && android::base::StartsWith(name, "persist.")) {
write_persistent_property(name.c_str(), value.c_str());
}
property_changed(name, value);
return PROP_SUCCESS;
}
Zygote也被称为孵化器。DVM和ART、应用程序进程、以及SystemService进程都是由它创建的。
Zygote进程启动主要做下面几件事
在init.rc文件中,采用如下Impoer语句引入了Zygote启动脚本
import /init.${ro.zygote}.rc
init.rc不是直接引入一个固定的文件,而是根据ro.zygote的内容来引入不同的文件。
从Android5.0开始,Android开始支持64位程序,Zygote也需要有32位和64位的区别,于是用ro.zygote属性来控制使用不同的Zygote启动脚本。ro.zygote属性的取值有以下4种
init.zygote32_64.rc文件如下
/system/core/rootdir/init.zygote32_64.rc
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
...
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote
class main
priority -20
user root
group root readproc
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
脚本中有两个Service语句,会启动两个Zygote进程,一个名为zygote作为主模式,一个名称为zygote_secondary,作为辅模式
Zygote进程启动时序图如下

/frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
...
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
//如果当前运行在Zygote进程中,则将zygote设置为true
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
//如果当前运行在SystemService进程中,则将startSystemServer设置为true
startSystemServer = true;
}
...
}
...
//如果运行在Zygote进程中
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
Zygote进程通过fock自身来创建子进程。这样Zygote进程以及它的子进程都可以进入app_main.cpp的main函数。main函数可以通过参数arg中是否包含了"–zygote"来确定当前是否为Zygote进程。如果是zygote进程会调用AppRuntime的start函数,如下所示
/frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//启动Java虚拟机
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//为Java虚拟机注册JNi方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
//此时,classNameStr为"com.android.internal.os.ZygoteInit"
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
//将className的"."替换为"/"(jni调用Java类需要全路径名称),替换后的值为"com/android/internal/os/ZygoteInit"
char* slashClassName = toSlashClassName(className);
//根据名字找到ZygoteInit类
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");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//通过JNI调用Zygote的Init的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
...
}
上面代码先是创建了虚拟机,然后再完成JNI方法的注册,最后通过JNI调用ZygoteInit的main方法。这样Zygote便进入了Java框架层。Zygote就是在此处开创了Java框架层。接下来看ZygoteInit的main方法
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
String socketName = "zygote";
...
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
//参数里有start-system-server表示要启动SystemServer进程
startSystemServer = true;
}
....
if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
}
...
}
...
//创建一个Server端的Socket,sockerName的值为"zygote"
zygoteServer.registerServerSocket(socketName);
// 在某些配置中,我们避免急切地预加载资源和类。 在这种情况下,我们将在第一次分叉之前预加载内容。
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
//预加载类
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
...
if (startSystemServer) {
//启动SystemServicer进程
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
//等待AMS请求创建新的进程
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
main方法主要做4件事
创建一个Servier的Socket
zygote通过registerServerSocket 方法来创建一个Server端的Socket,名为"zygote"的。它用于等待 AMS 请求Zygote 来创建新的应用程序进程。
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
//拼接Socker的名字。"ANDROID_SOCKET_"+"zygote"
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
//得到Socket的环境变量的值
String env = System.getenv(fullSocketName);
//将Socket环境变量的值转换为文件描述符的参数
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
//创建文件描述符
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
//创建服务端Socket,等待AMS请求Zygote进程来创建新的应用进程
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
预加载类和资源
启动SystemServer进程。
看startSystemServer方法
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
...
//创建atgs数组,用来保存启动SystemServer的启动参数
String args[] = {
//进城的用户id和用户组id都为1000。
"--setuid=1000",
"--setgid=1000",
//拥有用户组1001-1010、1018、1021、1032、3001-3010的权限;
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
//进程名字为system_server,启动的类名为"com.android.server.SystemServer"
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
//创建一个子进程,也就是SystemServer进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//如果当前代码运行在子进程(SystemServer进程)中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
//处理SystemServer进程
handleSystemServerProcess(parsedArgs);
}
return true;
}
等待Ams请求创建新的应用程序进程。
ZygoteServer 类的 runSelectLoop方法用于等待 Ams请求创建新的应用进程
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
//ZygoteConnection的连接列表
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
//mServerSocket是registerServerSocket函数创建的服务端Socket
//这里获取该Socket的fd字段的值并添加到fd列表fds中。
fds.add(mServerSocket.getFileDescriptor());//1
//让第0个为null
peers.add(null);
//无限循环等待AMS的请求
while (true) {
//临时数组,方便增删。pollFds个数为文件描述符的个数,起初为1
StructPollfd[] pollFds = new StructPollfd[fds.size()];
//将fds存储的信息转移到 pollFds数组中。
for (int i = 0; i < pollFds.length; ++i) {//2
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
//赋值为0
pollFds[i].events = (short) POLLIN;
}
try {
//poll()一直挂起直到一个指定事件发生
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
//能走到这里说明至少有一个fds就绪;
//对pollFds进行遍历
for (int i = pollFds.length - 1; i >= 0; --i) {//3
if ((pollFds[i].revents & POLLIN) == 0) {
//未就绪的fds跳过
continue;
}
if (i == 0) {
//i == 0说明服务端Socket与客户端连接上了,也就是Zygote进程和Ams建立了连接
//通过acceptCommandPeer得到ZygeteConnection对象。
ZygoteConnection newPeer = acceptCommandPeer(abiList);//4
//添加到连接列表
peers.add(newPeer);
//添加到fds中,while循环使用
fds.add(newPeer.getFileDesciptor());
} else {
//调用runOnce函数创建一个新的应用进程
boolean done = peers.get(i).runOnce(this);//5
if (done) {
//创建成功后,从连接列表移出
peers.remove(i);
fds.remove(i);
}
}
}
}
}
一开始初始化fds(文件描述符列表)、peers(连接列表)两个列表,首先将Socket的fd字段的值并添加到fds列表,然后再peers添加一个null对象,使其和fds个数对齐。
然后开启无限while循环,在循环内:
将fds数据存放到 pollFds临时数组中,然后调用Os.poll方法,挂起进程,直到一个fd就绪,下面才会执行
然后对pollFds的所有数据进行处理,第一次循环时只有一个fd就是socket的fd,走if (i == 0)语句块。表示有新的连接过来。然后对连接进行封装处理,并将这次连接的fd添加到fds。然后在下一次while循环处理
第二次循环时,fds有两个值。创建的pollFds临时数组也有两个值。第0个是Socket的fd,第1个是新连接的fd,然后走到Os.poll方法,由于新连接的fd还未处理,此时不会挂起。继续走到for循环,首先处理第一1fd,调用ZygoteConnection的runOnce方法,创建一个新的应用进程。创建成功后。将其从peers、fds中移出,然后走第0个fd,如果未就绪则跳过。继续走1,依次循环
SystemServer进程主要用于创建系统服务。AMS、WMS和PMS都由它来创建的。
Zygote进程启动SystemServer的时序图如下

Zygote进程在ZygoteInit的startSystemServer方法中启动了SystemServer进程
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
...
//如果当前代码运行在子进程(SystemServer进程)中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//关闭Zygote进程创建的Socket
zygoteServer.closeServerSocket();
//处理SystemServer进程
handleSystemServerProcess(parsedArgs);
}
return true;
}
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
...
if (parsedArgs.niceName != null) {
//设置进程名("system_server")
Process.setArgV0(parsedArgs.niceName);
}
...
if (parsedArgs.invokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//创建PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
//调用zygoteInit
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
...
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
//启动Binder线程池,ServerServer进程可以使用Binder与其他进程进行通信。
ZygoteInit.nativeZygoteInit();
//进入SystemServer的 main 方法
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
nativeZygoteInit是一个Native方法,在AndroidRuntime.cpp中注册
/frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};
return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
methods, NELEM(methods));
}
可以看到nativeZygoteInit方法对应的c++的方法为com_android_internal_os_ZygoteInit_nativeZygoteInit
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
gCurRuntime是AndroidRuntime类型的指针,具体指向的是AppRuntime(?),它在app_main.cpp中定义。
/frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
//启动一个Binder线程池。
proc->startThreadPool();
}
再回到zygoteInit方法里,接下来调用了RuntimeInit.applicationInit方法
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
...
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
Class<?> cl;
try {
//通过反射获取到Class(此处是com.android.server.SystemServer)
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
//找到该类的main方法
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
//抛出MethodAndArgsCaller异常
throw new Zygote.MethodAndArgsCaller(m, argv);
}
最后抛出了MethodAndArgsCaller异常,ZygoteInit.java的main方法会捕获该异常。这样做的好处是会清理掉所有设置过程中需要的堆栈帧,并让SystemServer的main方法看起来像是SystemServer进程的入口方法.
接下来看一下ZygoteInit.java的main方法是如何捕获MethodAndArgsCaller异常
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
...
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
这里直接调用了它的run方法
/frameworks/base/core/java/com/android/internal/os/Zygote.java
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** 要调用的方法 */
private final Method mMethod;
/** 方法的参数组 */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//反射调用mMethod方法。根据上面知道这里的mMethod是SystenServer的Main方法,
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
...
}
}
}
/frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
...
//创建消息Looper
Looper.prepareMainLooper();
//加载动态库libandroid_servers.so
System.loadLibrary("android_servers");
performPendingShutdown();
// 创建系统Context
createSystemContext();
// 创建SystemServiceManager,它会对系统服务进行创建、启动和声明周期管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// 为可并行化的 init 任务准备线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
try {
...
//启动引导服务(ActivityManagerService、PowerManagerService、PackageManagerService等)
startBootstrapServices();
//启动核心服务(DropBoxManagerService、BatteryService、UsageStatsService、WebViewUpdateService)
startCoreServices();
//启动其他服务(CameraService、AlarmManagerService、VrManagerService等)
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
...
} finally {
traceEnd();
}
...
// 开启无限循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Android官方将系统分为了三种类型,分别是引导服务、核心服务和其他服务。

这些服务的启动逻辑相似,例如PowerManagerService的启动代码如下
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
...
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
...
}
...
startService(service);
return service;
}
...
}
public void startService(@NonNull final SystemService service) {
//注册服务,将服务保存到列表里
mServices.add(service);
long time = System.currentTimeMillis();
try {
//启动服务
service.onStart();
} catch (RuntimeException ex) {
...
}
warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
}
SystemServer进程主要做了如下工作
系统启动的最后一步是启动一个应用程序用来显示系统中已经安装的应用程序,这个应用程序就叫Launcher
他主要有两个作用
SystemServer进程再启动过程中会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。然后Ams会将Launcher启动起来,Launch启动的时序图如下

启动Launch的入口为Ams的SystemReady方法,它在 SystemServer的startOtherServices方法中被调用
/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
...
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
...
}, BOOT_TIMINGS_TRACE_LOG);
}
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
...
synchronized (this) {
...
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
...
}
}
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
return false;
}
又调用了ActivityStack的resumeTopActivityUncheckedLocked方法,ActivityStack对象用来描述Activity堆栈。
/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
return false;
}
boolean result = false;
try {
//防止递归。
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
mStackSupervisor.checkReadyForSleepLocked();
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
final TaskRecord nextTask = next.getTask();
final TaskRecord prevTask = prev != null ? prev.getTask() : null;
if (prevTask != null && prevTask.getStack() == this &&
prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
...
else if (!isHomeStack()){
...
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(prev, "prevFinished");
}
}
...
}
又调用了ActivityStackSupervisor的resumeHomeStackTask方法
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
...
if (r != null && !r.finishing) {
moveFocusableActivityStackToFrontLocked(r, myReason);
return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
}
return mService.startHomeActivityLocked(mCurrentUser, myReason);
}
最后调用了startHomeActivityLocked方法
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
boolean startHomeActivityLocked(int userId, String reason) {
//判断工厂模式和mTopAction的值,符合要求就继续执行下去
//mTopAction用来描述第一个被启动Activity的Aciton,默认值为Intent.ACTION_MAIN。
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
//mFactoryTest表示系统的运行模式,有三种分别为。非工厂模式、低级工厂模式、高级工厂模式。此处表示如果是低级工厂模式并且mTopAction为null则返回
return false;
}
//创建launch启动所需的Intent
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
...
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
//判断『action为Intent.ACTION_MAIN、Category为Intent.CATEGORY_HOME』的应用是否已经启动
if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
//没有启动则调用startHomeActivityLocked启动该应用程序
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
//设置category为Intent.CATEGORY_HOME
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
startHomeActivityLocked方法启动了『action为Intent.ACTION_MAIN、Category为Intent.CATEGORY_HOME』的应用,而这个应用就是Launch应用
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher3">
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
...
<application
... >
<activity
android:name="com.android.launcher3.Launcher"
...>
<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>
接下来看startHomeActivityLocked的实现
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
//将Launcher放入HomeStack中
mSupervisor.moveHomeStackTaskToTop(reason);
mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,
null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,
null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,
null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,
null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
null /*container*/, null /*inTask*/, "startHomeActivity: " + reason);
...
}
这里会调用startActivityLocked方法来启动Launch。和Activity的启动过程类似。后面章节会有分析
先从Launcher的onCreate开始
/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
protected void onCreate(Bundle savedInstanceState) {
...
//获取LauncherAppState的实例
LauncherAppState app = LauncherAppState.getInstance(this);
mDeviceProfile = app.getInvariantDeviceProfile().getDeviceProfile(this);
...
mSharedPrefs = Utilities.getPrefs(this);
mIsSafeModeEnabled = getPackageManager().isSafeMode();
//设置Launcher对象
mModel = app.setLauncher(this);
...
// 如果启动器在前台时用户旋转(或触发配置更改),我们只会同步加载页面
int currentScreen = PagedView.INVALID_RESTORE_PAGE;
if (savedInstanceState != null) {
currentScreen = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN, currentScreen);
}
//调用startLoader开始加载
if (!mModel.startLoader(currentScreen)) {
mDragLayer.setAlpha(0);
} else {
mWorkspace.setCurrentPage(currentScreen);
setWorkspaceLoading(true);
}
...
}
app.setLauncher(this)方法将Launcher传入并获得LauncherModel类型的对象
/packages/apps/Launcher3/src/com/android/launcher3/LauncherAppState.java
LauncherModel setLauncher(Launcher launcher) {
getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);
//调用LauncherModel的initialize方法,传入launcher
mModel.initialize(launcher);
return mModel;
}
/packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java
public void initialize(Callbacks callbacks) {
//此处的callbacks是Launcher
synchronized (mLock) {
Preconditions.assertUIThread();
mHandler.cancelAll();
mCallbacks = new WeakReference<>(callbacks);
}
}
然后再看Launcher的OnCreate方法,调用了LauncherModel的startLoader方法
public boolean startLoader(int synchronousBindPage) {
...
synchronized (mLock) {
if (mCallbacks != null && mCallbacks.get() != null) {
...
//创建LoaderTask
mLoaderTask = new LoaderTask(mApp.getContext(), synchronousBindPage);
if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
&& mModelLoaded && !mIsLoaderTaskRunning) {
mLoaderTask.runBindSynchronousPage(synchronousBindPage);
return true;
} else {
sWorkerThread.setPriority(Thread.NORM_PRIORITY);
//将LoaderTask运行在sWorker所对应的HanderThread线程里
sWorker.post(mLoaderTask);
}
}
}
return false;
}
LoaderTask是LauncherModel的内部类,我们看它的run方法
private class LoaderTask implements Runnable {
...
public void run() {
synchronized (mLock) {
if (mStopped) {
return;
}
mIsLoaderTaskRunning = true;
}
try {
if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
mIsLoadingAndBindingWorkspace = true;
//加载工作区信息
loadWorkspace();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");
//绑定工作区信息
bindWorkspace(mPageToBindFirst);
if (DEBUG_LOADERS) Log.d(TAG, "step 1 completed, wait for idle");
waitForIdle();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");
//加载系统已安装的的应用程序信息
loadAllApps();
...
}
} catch (CancellationException e) {
// Loader stopped, ignore
} finally {
...
}
}
...
}
当LoaderTask执行时先是加载被绑定工作区信息。,然后调用loadAllApps方法加载系统已安装的应用程序
private void loadAllApps() {
...
//清理App列表
mBgAllAppsList.clear();
for (UserHandle user : profiles) {
final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
// 查询App 集合
final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
...
for (int i = 0; i < apps.size(); i++) {
LauncherActivityInfo app = apps.get(i);
// 这将构建图标位图。
mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
}
final ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(mContext, user);
if (heuristic != null) {
scheduleManagedHeuristicRunnable(heuristic, user, apps);
}
}
//临时列表保存
final ArrayList<AppInfo> added = mBgAllAppsList.added;
mBgAllAppsList.added = new ArrayList<AppInfo>();
// Post callback on main thread
mHandler.post(new Runnable() {
public void run() {
final long bindTime = SystemClock.uptimeMillis();
final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
//回调
callbacks.bindAllApplications(added);
...
} else {
Log.i(TAG, "not binding apps: no Launcher activity");
}
}
});
...
}
加载晚所有App信息后,切换到主线程调用callbacks对象bindAllApplications方法,而callbacks其实是Launcher对象
/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public void bindAllApplications(final ArrayList<AppInfo> apps) {
if (waitUntilResume(mBindAllApplicationsRunnable, true)) {
mTmpAppsList = apps;
return;
}
if (mAppsView != null) {
//将App信息传到View里
mAppsView.setApps(apps);
}
if (mLauncherCallbacks != null) {
mLauncherCallbacks.bindAllApplications(apps);
}
}
/packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java
public void setApps(List<AppInfo> apps) {
//在mApps对象中保存应用信息列表apps,mApps是一个AlphabeticalAppsList的对象
mApps.setApps(apps);
}
当AllAppsContainerView加载完Xml布局后会调用onFinishInflate方法
@Override
protected void onFinishInflate() {
super.onFinishInflate();
...
//找到显示App列表的mAppsRecyclerView
mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);
将mApps设置进去
mAppsRecyclerView.setApps(mApps);
mAppsRecyclerView.setLayoutManager(mLayoutManager);
//设置Adapter
mAppsRecyclerView.setAdapter(mAdapter);
...
}
在onFinishInflate方法里,完成了App列表的设置显示,至此应用程序的快捷图标就显示在屏幕上了