首先要感谢**@刘望舒**大神的博客,让我们这些渣渣有途径更快速地接触到Android框架层的内容。
本篇博客主要基于Android7.0来分析Android系统的启动流程。
init进程是Android系统中用户空间的第一个进程。
作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等等。i由多个源文件共同组成,这些文件位于源码目录system/core/init。
我们首先需要了解系统启动流程的前几步。
1. 电源及系统的启动
当电源按下时,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
2. 引导程序Bootloader
引导程序是Android系统开始运行前的一个小程序,它可以把系统OS拉起并运行。
3. Linux内核启动
内核启动时,会通过设置缓存、被保护存储器、计划列表,加载驱动等等过程。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动root进程或者系统的第一个进程。
4. 启动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());
parser.AddSectionParser("on", std::make_unique());
parser.AddSectionParser("import", std::make_unique());
//解析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方法中做了很多事情,我们需要关注的是下面几点:
property_init
函数对属性初始化start_property_service()
函数启动属性服务parser.ParseConfig(“/init.rc”)
解析 init.rc 文件。(解析init.rc的源文件位于system/core/init/init_parse.cpp)接下来我们看看 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 [&& ]* //设置触发器
//动作触发之后要执行的命令
为了分析如何创建zygote,我们需要查看Services类型语句,它的格式如下:
service [ ]* //<执行程序路径><传递参数>
在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,它会用到两个函数:
ParseSection函数用于解析service的rc文件,如init.zygoteXX.rc。
ParseSection函数主要用来搭建service的架子。另一个是ParseLineSection,用于解析子项。
service位于system/core/init/service.cpp
bool ServiceParser::ParseSection(const std::vector& 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 str_args(args.begin() + 2, args.end());
service_ = std::make_unique(name, "default", str_args);//1
return true;
}
bool ServiceParser::ParseLineSection(const std::vector& 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* 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链表中。
分析完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& 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进程主要做了三件事:
1.创建一些文件夹并挂载设备
2.初始化和启动属性服务
3.解析init.rc配置文件并启动zygote进程
前面我们了解到在init进程中启动了zygote进程,那么zygote进程又做了什么操作呢?
在Android中,Dalvik、应用程序进程及运行系统的关键服务的SystemServer进程均是由Zygote进程来创建,因此我们称Zygote线程为孵化器。它通过 fork(复制进程)的形式创建应用程序进程和 SystemServer 进程。由于Zygote启动时创建了Dalvik,因此通过fork创建的应用程序进程和SystemServer进程可以在内部获取一个Dalvik的实例拷贝。
从前文可以知道init启动zygote是调用app_main.cpp的main中AppRuntime
的start
方法来启动zygote进程。我们从app_main.cpp的main开始分析
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...
Vector 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& 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调用。
前文中我们在AndroidRuntime的start
方法中通过JNI调用了ZygoteInit
的main
函数,之后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件事
接下来我们对主要的事件一一进行分析。
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进程来创建新的应用程序进程。
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进程。
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进程中通过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进程。
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层的代码)
接下来我们看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 proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();//1
}
注释1处用来启动一个Binder线程池,这样SyetemServer进程就可以使用Binder来与其他进程进行通信了。
看到这里我们知道RuntimeInit.java
的nativeZygoteInit
函数主要做的就是启动Binder线程池。
我们回到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的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进程启动时做了如下工作:
前面我们介绍了Init进程、Zygote进程、SystemServer进程的启动流程,下面我们介绍系统启动的最后一步——Launcher的启动过程。
Android系统的启动的最后一步是启动一个Home应用程序,用于显示我们已经安装的各类应用程序。这个Home应用程序就是我们所说的Launcher。在启动Launcher时会请求PackageManagerService返回系统中已经安装的应用程序的信息,并且将这些信息封装为快捷图标列表显示在屏幕上,便于用户点击来启动相应应用程序。
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应用的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 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。
这样,就成功的将应用程序的快捷方式显示在了屏幕上
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启动后会将已安装应用的快捷图标显示到界面上。