赞
踩
Android系统启动过程往细了说可以分为5步:
Loader --》Kernel --》Native --》Framework --》Application
Kernel层是指Android内核层,到这里才刚刚开始进入Android系统
这里的Native层主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖
这些层之间,有的并不能直接交流,比如Native与Kernel之间要经过系统调用才能访问,Java层和Native层需要通过JNI进行调用
严格来说,Android系统实际上是运行于Linux内核上的一系列服务进程,这些进程是维持设备正常运行的关键,而这些进程的老祖宗就是init进程
上面也介绍到了,当内核启动完成后,就会创建用户空间的第一个进程,即init进程;后面所有的进程,比如Binder机制中的ServiceManager,Zygote都是由init进程孵化出来的
当init进程启动后会调用/system/core/init/Init.cpp的main()方法
int main(int argc, char** argv) { ... klog_init(); //初始化kernel log,位于设备节点/dev/kmsg klog_set_level(KLOG_NOTICE_LEVEL); //设置输出的log级别 // 输出init启动阶段的log NOTICE("init%s started!\n", is_first_stage ? "" : " second stage"); property_init(); //创建一块共享的内存空间,用于属性服务 signal_handler_init(); //初始化子进程退出的信号处理过程 property_load_boot_defaults(); //加载default.prop文件 start_property_service(); //启动属性服务器(通过socket通信) init_parse_config_file("/init.rc"); //解析init.rc文件 //执行rc文件中触发器为 on early-init的语句 action_for_each_trigger("early-init", action_add_queue_tail); //等冷插拔设备初始化完成 queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); //设备组合键的初始化操作 queue_builtin_action(keychord_init_action, "keychord_init"); // 屏幕上显示Android静态Logo queue_builtin_action(console_init_action, "console_init"); //执行rc文件中触发器为 on init的语句 action_for_each_trigger("init", action_add_queue_tail); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); char bootmode[PROP_VALUE_MAX]; //当处于充电模式,则charger加入执行队列;否则late-init加入队列。 if (property_get("ro.bootmode", bootmode) > 0 && strcmp(bootmode, "charger") == 0) { action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("late-init", action_add_queue_tail); } //触发器为属性是否设置 queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); while (true) { if (!waiting_for_exec) { execute_one_command(); restart_processes(); } int timeout = -1; if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) { timeout = 0; } 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; }
这里很重要的一句话就是init_parse_config_file,然后去解析init.rc文件,init.rc位于/bootable/recovery/etc/init.rc;需要注意的是这就是一个脚本文件,就像Android打包用到的gradle脚本一样
这个文件解析具体实现在init_parser.cpp文件中,一个完整的init.rc脚本由四种类型的声明组成
rc文件有一些通用的语法规则
Actions代表一些Action,Action代表一组命令(Commands),每个Action都有一个trigger(触发器),这个触发器决定了在什么情况下执行该Action中定义的命令;当一些条件满足触发器的条件时,该Action中定义的命令会被添加到“命令执行队列”的尾部,如果命令已经存在了就不会再添加了
Action的格式如下
on <trgger> ## on后面接触发条件
<command1> ## 命令1
<command2> ## 命令2
<command3> ## 命令3
...
不同的脚本用【on】来区分,on后面跟一个触发器,当被触发时,下面的命令就会以此执行
常用的有以下几种事件触发器
类型 说明
-------------------------------------------------
boot init.rc被装载后触发
device-added-<path> 当设备节点添加时触发
device-removed-<path> 当设备节点移除时触发
service-exited-<name> 在指定的服务(service)退出时触发
early-init init程序初始化之前触发
late-init init程序初始化之后触发
init 初始化时触发(在 /init.conf (启动配置文件)被装载之后)
Service其实是一个可执行程序,以service开头的脚本,在特定选项的约束下会被init程序启动或者重启(Service可以在配置中指定是否需要在退出时重启,这样当Service出现crash时就可以有机会复原)
脚本格式如下
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
可用选项如下,也就是上面Service所用到的< option>
# Copyright (C) 2012 The Android Open Source Project # # IMPORTANT: Do not create world writable files or directories. # This is a common source of Android security bugs. # "【import <filename>一个init配置文件,扩展当前配置。】" import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc import /init.${ro.zygote}.rc import /init.trace.rc "【触发条件early-init,在early-init阶段调用以下行】" on early-init # Set init and its forked children's oom_adj. write /proc/1/oom_score_adj -1000 "【打开路径为<path>的一个文件,并写入一个或多个字符串】" # Apply strict SELinux checking of PROT_EXEC on mmap/mprotect calls. write /sys/fs/selinux/checkreqprot 0 # Set the security context for the init process. # This should occur before anything else (e.g. ueventd) is started. "【这段脚本的意思是init进程启动之后就马上调用函数setcon将自己的安全上下文设置为“u:r:init:s0”,即将init进程的domain指定为init。】" setcon u:r:init:s0 # Set the security context of /adb_keys if present. "【恢复指定文件到file_contexts配置中指定的安全上线文环境】" restorecon /adb_keys "【执行start ueventd的命令。ueventd是一个service后面有定义】 " start ueventd "【mkdir <path> [mode] [owner] [group] //创建一个目录<path>,可以选择性地指定mode、owner以及group。如果没有指定,默认的权限为755,并属于root用户和root组。】" # create mountpoints mkdir /mnt 0775 root system on init "【设置系统时钟的基准,比如0代表GMT,即以格林尼治时间为准】" sysclktz 0 "【设置kernel日志等级】" loglevel 6 #### write /proc/bootprof "INIT: on init start" #### "【symlink <target> <path> //创建一个指向<path>的软连接<target>。】" # Backward compatibility symlink /system/etc /etc symlink /sys/kernel/debug /d # Right now vendor lives on the same filesystem as system, # but someday that may change. symlink /system/vendor /vendor "【创建一个目录<path>,可以选择性地指定mode、owner以及group。】" # Create cgroup mount point for cpu accounting mkdir /acct mount cgroup none /acct cpuacct mkdir /acct/uid "【mount <type> <device> <dir> [ <mountoption> ] //在目录<dir>挂载指定的设备。<device> 可以是以 mtd@name 的形式指定一个mtd块设备。<mountoption>包括 ro、rw、remount、noatime、 ...】" # Create cgroup mount point for memory mount tmpfs none /sys/fs/cgroup mode=0750,uid=0,gid=1000 mkdir /sys/fs/cgroup/memory 0750 root system mount cgroup none /sys/fs/cgroup/memory memory write /sys/fs/cgroup/memory/memory.move_charge_at_immigrate 1 "【chown <owner> <group> <path> //改变文件的所有者和组。】" "【后面的一些行因为类似,就省略了】" ..... # Healthd can trigger a full boot from charger mode by signaling this # property when the power button is held. on property:sys.boot_from_charger_mode=1 "【停止指定类别服务类下的所有已运行的服务】" class_stop charger "【触发一个事件,将该action排在某个action之后(用于Action排队)】" trigger late-init # Load properties from /system/ + /factory after fs mount. on load_all_props_action "【从/system,/vendor加载属性。默认包含在init.rc】" load_all_props # Indicate to fw loaders that the relevant mounts are up. on firmware_mounts_complete "【删除指定路径下的文件】" rm /dev/.booting # Mount filesystems and start core system services. on late-init "【触发一个事件。用于将一个action与另一个 action排列。】" trigger early-fs trigger fs trigger post-fs trigger post-fs-data # Load properties from /system/ + /factory after fs mount. Place # this in another action so that the load will be scheduled after the prior # issued fs triggers have completed. trigger load_all_props_action # Remove a file to wake up anything waiting for firmware. trigger firmware_mounts_complete trigger early-boot trigger boot on post-fs ... "【一些创造目录,建立链接,更改权限的操作,这里省略】" on post-fs-data ... "【一些创造目录,建立链接,更改权限的操作,这里省略】" "【恢复指定文件到file_contexts配置中指定的安全上线文环境】" restorecon /data/mediaserver "【将系统属性<name>的值设置为<value>,即以键值对的方式设置系统属性】" # Reload policy from /data/security if present. setprop selinux.reload_policy 1 "【以递归的方式恢复指定目录到file_contexts配置中指定的安全上下文中】" # Set SELinux security contexts on upgrade or policy update. restorecon_recursive /data # If there is no fs-post-data action in the init.<device>.rc file, you # must uncomment this line, otherwise encrypted filesystems # won't work. # Set indication (checked by vold) that we have finished this action #setprop vold.post_fs_data_done 1 on boot "【初始化网络】" # basic network init ifup lo "【设置主机名为localhost】" hostname localhost "【设置域名localdomain】" domainname localdomain "【设置资源限制】" # set RLIMIT_NICE to allow priorities from 19 to -20 setrlimit 13 40 40 "【这里省略了一些chmod,chown,等操作,不多解释】" ... # Define default initial receive window size in segments. setprop net.tcp.default_init_rwnd 60 "【重启core服务】" class_start core on nonencrypted class_start main class_start late_start on property:vold.decrypt=trigger_default_encryption start defaultcrypto on property:vold.decrypt=trigger_encryption start surfaceflinger start encrypt on property:sys.init_log_level=* loglevel ${sys.init_log_level} on charger class_start charger on property:vold.decrypt=trigger_reset_main class_reset main on property:vold.decrypt=trigger_load_persist_props load_persist_props on property:vold.decrypt=trigger_post_fs_data trigger post-fs-data on property:vold.decrypt=trigger_restart_min_framework class_start main on property:vold.decrypt=trigger_restart_framework class_start main class_start late_start on property:vold.decrypt=trigger_shutdown_framework class_reset late_start class_reset main on property:sys.powerctl=* powerctl ${sys.powerctl} # system server cannot write to /proc/sys files, # and chown/chmod does not work for /proc/sys/ entries. # So proxy writes through init. on property:sys.sysctl.extra_free_kbytes=* write /proc/sys/vm/extra_free_kbytes ${sys.sysctl.extra_free_kbytes} # "tcp_default_init_rwnd" Is too long! on property:sys.sysctl.tcp_def_init_rwnd=* write /proc/sys/net/ipv4/tcp_default_init_rwnd ${sys.sysctl.tcp_def_init_rwnd} "【守护进程】" ## Daemon processes to be run by init. ## service ueventd /sbin/ueventd class core critical seclabel u:r:ueventd:s0 "【日志服务进程】" service logd /system/bin/logd class core socket logd stream 0666 logd logd socket logdr seqpacket 0666 logd logd socket logdw dgram 0222 logd logd seclabel u:r:logd:s0 "【Healthd是android4.4之后提出来的一种中介模型,该模型向下监听来自底层的电池事件,向上传递电池数据信息给Framework层的BatteryService用以计算电池电量相关状态信息】" service healthd /sbin/healthd class core critical seclabel u:r:healthd:s0 "【控制台进程】" service console /system/bin/sh "【为当前service设定一个类别.相同类别的服务将会同时启动或者停止,默认类名是default】" class core "【服务需要一个控制台】" console "【服务不会自动启动,必须通过服务名显式启动】" disabled "【在执行此服务之前切换用户名,当前默认的是root.自Android M开始,即使它要求linux capabilities,也应该使用该选项.很明显,为了获得该功能,进程需要以root用户运行】" user shell seclabel u:r:shell:s0 on property:ro.debuggable=1 start console # 启动adbd服务进程 service adbd /sbin/adbd --root_seclabel=u:r:su:s0 class core "【创建一个unix域下的socket,其被命名/dev/socket/<name>. 并将其文件描述符fd返回给服务进程.其中,type必须为dgram,stream或者seqpacke,user和group默认是0.seclabel是该socket的SELLinux的安全上下文环境,默认是当前service的上下文环境,通过seclabel指定】" socket adbd stream 660 system system disabled seclabel u:r:adbd:s0 # adbd on at boot in emulator on property:ro.kernel.qemu=1 start adbd "【内存管理服务,内存不够释放内存】" service lmkd /system/bin/lmkd class core critical socket lmkd seqpacket 0660 system system "【ServiceManager是一个守护进程,它维护着系统服务和客户端的binder通信。 在Android系统中用到最多的通信机制就是Binder,Binder主要由Client、Server、ServiceManager和Binder驱动程序组成。其中Client、Service和ServiceManager运行在用户空间,而Binder驱动程序运行在内核空间。核心组件就是Binder驱动程序了,而ServiceManager提供辅助管理的功能,无论是Client还是Service进行通信前首先要和ServiceManager取得联系。而ServiceManager是一个守护进程,负责管理Server并向Client提供查询Server的功能。】" service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart healthd "【servicemanager 服务启动时会重启zygote服务】" onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm "【Vold是Volume Daemon的缩写,它是Android平台中外部存储系统的管控中心,是管理和控制Android平台外部存储设备的后台进程】" service vold /system/bin/vold class core socket vold stream 0660 root mount ioprio be 2 "【Netd是Android系统中专门负责网络管理和控制的后台daemon程序】" service netd /system/bin/netd class main socket netd stream 0660 root system socket dnsproxyd stream 0660 root inet socket mdns stream 0660 root system socket fwmarkd stream 0660 root inet "【debuggerd是一个daemon进程,在系统启动时随着init进程启动。主要负责将进程运行时的信息dump到文件或者控制台中】" service debuggerd /system/bin/debuggerd class main service debuggerd64 /system/bin/debuggerd64 class main "【Android RIL (Radio Interface Layer)提供了Telephony服务和Radio硬件之间的抽象层】" # for using TK init.modem.rc rild-daemon setting #service ril-daemon /system/bin/rild # class main # socket rild stream 660 root radio # socket rild-debug stream 660 radio system # user root # group radio cache inet misc audio log "【提供系统 范围内的surface composer功能,它能够将各种应用 程序的2D、3D surface进行组合。】" service surfaceflinger /system/bin/surfaceflinger class core user system group graphics drmrpc onrestart restart zygote "【DRM可以直接访问DRM clients的硬件。DRM驱动用来处理DMA,内存管理,资源锁以及安全硬件访问。为了同时支持多个3D应用,3D图形卡硬件必须作为一个共享资源,因此需要锁来提供互斥访问。DMA传输和AGP接口用来发送图形操作的buffers到显卡硬件,因此要防止客户端越权访问显卡硬件。】" #make sure drm server has rights to read and write sdcard #### service drm /system/bin/drmserver class main user drm # group drm system inet drmrpc #### group drm system inet drmrpc sdcard_r #### "【媒体服务,无需多说】" service media /system/bin/mediaserver class main user root #### # google default #### # user media #### group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm media sdcard_r system net_bt_stack #### # google default #### # group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm #### ioprio rt 4 "【设备加密相关服务】" # One shot invocation to deal with encrypted volume. service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted disabled "【当服务退出时,不重启该服务】" oneshot # vold will set vold.decrypt to trigger_restart_framework (default # encryption) or trigger_restart_min_framework (other encryption) # One shot invocation to encrypt unencrypted volumes service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default disabled oneshot # vold will set vold.decrypt to trigger_restart_framework (default # encryption) "【开机动画服务】" service bootanim /system/bin/bootanimation class core user graphics # group graphics audio #### group graphics media audio #### disabled oneshot "【在Android系统中,PackageManagerService用于管理系统中的所有安装包信息及应用程序的安装卸载,但是应用程序的安装与卸载并非PackageManagerService来完成,而是通过PackageManagerService来访问installd服务来执行程序包的安装与卸载的。】" service installd /system/bin/installd class main socket installd stream 600 system system service flash_recovery /system/bin/install-recovery.sh class main seclabel u:r:install_recovery:s0 oneshot "【vpn相关的服务】" service racoon /system/bin/racoon class main socket racoon stream 600 system system # IKE uses UDP port 500. Racoon will setuid to vpn after binding the port. group vpn net_admin inet disabled oneshot "【android中有mtpd命令可以连接vpn】" service mtpd /system/bin/mtpd class main socket mtpd stream 600 system system user vpn group vpn net_admin inet net_raw disabled oneshot service keystore /system/bin/keystore /data/misc/keystore class main user keystore group keystore drmrpc "【可以用dumpstate 获取设备的各种信息】" service dumpstate /system/bin/dumpstate -s class main socket dumpstate stream 0660 shell log disabled oneshot "【mdnsd 是多播 DNS 和 DNS 服务发现的守护程序。】" service mdnsd /system/bin/mdnsd class main user mdnsr group inet net_raw socket mdnsd stream 0660 mdnsr inet disabled oneshot "【触发关机流程继续往下走】" service pre-recovery /system/bin/uncrypt class main disabled "【当服务退出时,不重启该服务】" oneshot
启动顺序是on early-init -> init -> late-init -> boot,接下来就是各种服务的启动
在Android中,zygote是整个系统创建新进程的核心进程。在init进程启动后就会创建zygote进程;zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态。在之后的运作中,当其他系统模块(比如AMS)希望创建新进程时,只需向zygote进程发出请求,zygote进程监听到该请求后,会相应地fork出新的进程,于是这个新进程在初生之时,就先天具有了自己的Dalvik虚拟机以及系统资源
其实在早期的Android版本中,Zygote的启动命令直接是写在init.rc中的,但是随着硬件的不断升级换代,Android系统也要面对32位和64位机器同时存在的情况,所以对Zygote启动也需要根据不同情况对待
在init.rc顶部可以看到有这么一句话
import /init.${ro.zygote}.rc
这里会根据系统属性ro.zygote的值去加载不同的描述Zygote的rc脚本,比如
以init.zygote64_32.rc为例
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote 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 service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary class main socket zygote_secondary stream 660 root system onrestart restart zygote writepid /dev/cpuset/foreground/tasks
如上,可以看到服务名(进程名)是zygote,对应的可执行程序是app_processXX,而且还创建了一个名为zygote的unix domain socket,类型是stream,这个socket是为了后面IPC所用;上面可以看到还有一个zygote_secondary的进程,其实这是为了适配不同的abi型号
其中Zygote进程能够重启的地方有
接下来看看zygote启动过程,zygote对应的可执行文件就是/system/bin/app_processXX,也就是说系统启动时会执行到这个可执行文件的main()函数里
int main(int argc, char* const argv[]) { //Android运行时环境,传到的参数argv为“-Xzygote /system/bin --zygote --start-system-server” AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); argc--; argv++; //忽略第一个参数 int i; for (i = 0; i < argc; i++) { if (argv[i][0] != '-') { break; } if (argv[i][1] == '-' && argv[i][2] == 0) { ++i; break; } runtime.addOption(strdup(argv[i])); } //参数解析 bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; //--zygote表示当前进程用于承载zygote //对于64位系统nice_name为zygote64; 32位系统为zygote niceName = ZYGOTE_NICE_NAME; } else if (strcmp(arg, "--start-system-server") == 0) { //是否需要启动system server startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { //启动进入独立的程序模式 application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { //niceName 为当前进程别名,区别abi型号 niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } Vector<String8> args; if (!className.isEmpty()) { // 运行application或tool程序 args.add(application ? String8("application") : String8("tool")); runtime.setClassNameAndArgs(className, argc - i, argv + i); } else { //进入zygote模式,创建 /data/dalvik-cache路径 maybeCreateDalvikCache(); if (startSystemServer) { args.add(String8("start-system-server")); } char prop[PROP_VALUE_MAX]; if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { 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); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } else { //没有指定类名或zygote,参数错误 return 10; } }
根据传入参数的不同可以有两种启动方式,一个是 “com.android.internal.os.RuntimeInit”, 另一个是 ”com.android.internal.os.ZygoteInit", 对应RuntimeInit 和 ZygoteInit 两个类, 这两个类的主要区别在于Java端,可以明显看出,ZygoteInit 相比 RuntimeInit 多做了很多事情,比如说 “preload", “gc” 等等。但是在Native端,他们都做了相同的事, startVM() 和 startReg()
在当前场景中,init.rc指定了–zygote选项,并且args有添加start-system-server值,所以接下来执行
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { static const String8 startSystemServer("start-system-server"); for (size_t i = 0; i < options.size(); ++i) { if (options[i] == startSystemServer) { const int LOG_BOOT_PROGRESS_START = 3000; } } const char* rootDir = getenv("ANDROID_ROOT"); if (rootDir == NULL) { rootDir = "/system"; if (!hasDir("/system")) { return; } setenv("ANDROID_ROOT", rootDir, 1); } JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; // 虚拟机创建,主要篇幅是关于虚拟机参数的设置 if (startVm(&mJavaVM, &env, zygote) != 0) { return; } onVmCreated(env); // JNI方法注册 if (startReg(env) < 0) { return; } jclass stringClass; jobjectArray strArray; jstring classNameStr; //等价 strArray= new String[options.size() + 1]; stringClass = env->FindClass("java/lang/String"); strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); //等价 strArray[0] = "com.android.internal.os.ZygoteInit" classNameStr = env->NewStringUTF(className); env->SetObjectArrayElement(strArray, 0, classNameStr); //等价 strArray[1] = "start-system-server"; // strArray[2] = "--abi-list=xxx"; //其中xxx为系统响应的cpu架构类型,比如arm64-v8a. for (size_t i = 0; i < options.size(); ++i) { jstring optionsStr = env->NewStringUTF(options.itemAt(i).string()); env->SetObjectArrayElement(strArray, i + 1, optionsStr); } //将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit" char* slashClassName = toSlashClassName(className); //找到Zygoteinit类 jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ... } else { //找到这个类后就继续找成员函数main方法的Mehtod ID jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); // 通过反射调用ZygoteInit.main()方法 env->CallStaticVoidMethod(startClass, startMeth, strArray); } //释放相应对象的内存空间 free(slashClassName); mJavaVM->DetachCurrentThread(); mJavaVM->DestroyJavaVM(); }
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) { // JNI检测功能,用于native层调用jni函数时进行常规检测,比较弱字符串格式是否符合要求,资源是否正确释放。该功能一般用于早期系统调试或手机Eng版,对于User版往往不会开启,引用该功能比较消耗系统CPU资源,降低系统性能。 bool checkJni = false; property_get("dalvik.vm.checkjni", propBuf, ""); if (strcmp(propBuf, "true") == 0) { checkJni = true; } else if (strcmp(propBuf, "false") != 0) { property_get("ro.kernel.android.checkjni", propBuf, ""); if (propBuf[0] == '1') { checkJni = true; } } if (checkJni) { addOption("-Xcheck:jni"); } //虚拟机产生的trace文件,主要用于分析系统问题,路径默认为/data/anr/traces.txt parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:"); //对于不同的软硬件环境,这些参数往往需要调整、优化,从而使系统达到最佳性能 parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m"); parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m"); parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit="); parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree="); parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree="); parseRuntimeOption("dalvik.vm.heaptargetutilization", heaptargetutilizationOptsBuf, "-XX:HeapTargetUtilization="); ... //preloaded-classes文件内容是由WritePreloadedClassFile.java生成的, //在ZygoteInit类中会预加载工作将其中的classes提前加载到内存,以提高系统性能 if (!hasFile("/system/etc/preloaded-classes")) { return -1; } //初始化虚拟机 if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { ALOGE("JNI_CreateJavaVM failed\n"); return -1; } }
int AndroidRuntime::startReg(JNIEnv* env)
{
//设置线程创建方法为javaCreateThreadEtc
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
env->PushLocalFrame(200);
//进程JNI方法的注册
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL);
return 0;
}
总结一下Zygote native 进程做了哪些主要工作:
这就开始进入java层了
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) { try { RuntimeInit.enableDdms(); //开启DDMS功能 SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } ... registerZygoteSocket(socketName); //为Zygote注册socket preload(); // 预加载类和资源 SamplingProfilerIntegration.writeZygoteSnapshot(); gcAndFinalize(); //GC操作 if (startSystemServer) { startSystemServer(abiList, socketName);//启动system_server } runSelectLoop(abiList); //进入循环模式 closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); //启动system_server中会讲到。 } catch (RuntimeException ex) { closeServerSocket(); throw ex; } }
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) { ... } try { FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); //设置文件描述符 sServerSocket = new LocalServerSocket(fd); //创建Socket的本地服务端 } catch (IOException ex) { ... } } }
在这里就是实例化一个LocalServerSocket,这样zygote就可以作为服务端,不断的获取其它进程发送过来的请求
static void preload() { //预加载位于/system/etc/preloaded-classes文件中的类 preloadClasses(); //预加载资源,包含drawable和color资源 preloadResources(); //预加载OpenGL preloadOpenGL(); //通过System.loadLibrary()方法, //预加载"android","compiler_rt","jnigraphics"这3个共享库 preloadSharedLibraries(); //预加载 文本连接符资源 preloadTextResources(); //仅用于zygote进程,用于内存共享的进程 WebViewFactory.prepareWebViewInZygote(); }
执行Zygote进程的初始化,对于类加载,采用反射机制Class.forName()方法来加载。对于资源加载,主要是 com.android.internal.R.array.preloaded_drawables和com.android.internal.R.array.preloaded_color_state_lists,在应用程序中以com.android.internal.R.xxx开头的资源,便是此时由Zygote加载到内存的
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); //sServerSocket是socket通信中的服务端,即zygote进程。保存到fds[0] fds.add(sServerSocket.getFileDescriptor()); peers.add(null); while (true) { StructPollfd[] pollFds = new StructPollfd[fds.size()]; for (int i = 0; i < pollFds.length; ++i) { pollFds[i] = new StructPollfd(); pollFds[i].fd = fds.get(i); pollFds[i].events = (short) POLLIN; } try { //处理轮询状态,当pollFds有事件到来则往下执行,否则阻塞在这里 Os.poll(pollFds, -1); } catch (ErrnoException ex) { ... } for (int i = pollFds.length - 1; i >= 0; --i) { //采用I/O多路复用机制,当接收到客户端发出连接请求 或者数据处理请求到来,则往下执行; // 否则进入continue,跳出本次循环。 if ((pollFds[i].revents & POLLIN) == 0) { continue; } if (i == 0) { //即fds[0],代表的是sServerSocket,则意味着有客户端连接请求; // 则创建ZygoteConnection对象,并添加到fds。 ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); //添加到fds. } else { //i>0,则代表通过socket接收来自对端的数据,并执行相应操作 boolean done = peers.get(i).runOnce(); if (done) { peers.remove(i); fds.remove(i); //处理完则从fds中移除该文件描述符 } } } } }
private static ZygoteConnection acceptCommandPeer(String abiList) {
try {
return new ZygoteConnection(sServerSocket.accept(), abiList);
} catch (IOException ex) {
...
}
}
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; try { //读取socket客户端发送过来的参数列表 args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { ... return true; } ... try { //将binder客户端传递过来的参数,解析成Arguments对象格式 parsedArgs = new Arguments(args); ... pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, parsedArgs.appDataDir); } catch (Exception e) { ... } try { if (pid == 0) { //子进程执行 IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; //进入子进程流程 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); return true; } else { //父进程执行 IoUtils.closeQuietly(childPipeFd); childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } }
接收客户端发送过来的connect()操作,Zygote作为服务端执行accept()操作。 再后面客户端调用write()写数据,Zygote进程调用read()读数据。
没有连接请求时会进入休眠状态,当有创建新进程的连接请求时,唤醒Zygote进程,创建Socket通道ZygoteConnection,然后执行ZygoteConnection的runOnce()方法。
system server进程和zygote进程可以说是Android世界中的两大最重要的进程,离开其中之一基本上系统就玩完了;基本上在Java Framework中的大多数服务都是在system server进程中一个线程的方式存在的,如下:
system server进程也是由zygote进程fork出来的,在上面的ZygoteInit.main方法中有如下代码
public static void main(String argv[]) {
try {
if (startSystemServer) {
startSystemServer(abiList, socketName);//启动system_server
}
} catch (MethodAndArgsCaller caller) {
caller.run(); //这一步很重要,接下来会讲到
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { ... //参数准备 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", "--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); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); // fork子进程,该进程是system_server进程 pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } //进入子进程system_server if (pid == 0) { //第二个zygote进程 if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } // 完成system_server进程剩余的工作 handleSystemServerProcess(parsedArgs); } return true; }
这个方法先准备参数,然后fork新进程,对于有两个zygote进程情况,需等待第2个zygote创建完成
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
// 调用native方法fork system_server进程
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}
nativeForkSystemServer()方法在AndroidRuntime.cpp中注册的,调用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法建立native方法的映射关系,所以接下来进入如下方法
static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities, jlong effectiveCapabilities) { //fork子进程 pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL, NULL, NULL); if (pid > 0) { // zygote进程,检测system_server进程是否创建 gSystemServerPid = pid; int status; if (waitpid(pid, &status, WNOHANG) == pid) { //当system_server进程死亡后,重启zygote进程 RuntimeAbort(env); } } return pid; }
当system_server进程创建失败时,将会重启zygote进程。这里需要注意,对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,system_server的父进程,一般来说64位系统其父进程是zygote64进程
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, jstring instructionSet, jstring dataDir) { SetSigChldHandler(); //设置子进程的signal信号处理函数 pid_t pid = fork(); //fork子进程 if (pid == 0) { //进入子进程 DetachDescriptors(env, fdsToClose); //关闭并清除文件描述符 if (!is_system_server) { //对于非system_server子进程,则创建进程组 int rc = createProcessGroup(uid, getpid()); } SetGids(env, javaGids); //设置设置group SetRLimits(env, javaRlimits); //设置资源limit int rc = setresgid(gid, gid, gid); rc = setresuid(uid, uid, uid); SetCapabilities(env, permittedCapabilities, effectiveCapabilities); SetSchedulerPolicy(env); //设置调度策略 //selinux上下文 rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str); if (se_info_c_str == NULL && is_system_server) { se_name_c_str = "system_server"; } if (se_info_c_str != NULL) { SetThreadName(se_name_c_str); //设置线程名为system_server,方便调试 } UnsetSigChldHandler(); //设置子进程的signal信号处理函数为默认函数 //等价于调用zygote.callPostForkChildHooks() env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags, is_system_server ? NULL : instructionSet); ... } else if (pid > 0) { //进入父进程,即zygote进程 } return pid; } int fork() { __bionic_atfork_run_prepare(); pthread_internal_t* self = __get_thread(); //fork期间,获取父进程pid,并使其缓存值无效 pid_t parent_pid = self->invalidate_cached_pid(); //系统调用 int result = syscall(__NR_clone, FORK_FLAGS, NULL, NULL, NULL, &(self->tid)); if (result == 0) { self->set_cached_pid(gettid()); __bionic_atfork_run_child(); //fork完成执行子进程回调方法 } else { self->set_cached_pid(parent_pid); __bionic_atfork_run_parent(); //fork完成执行父进程回调方法 } return result; }
fork()采用copy on write技术,这是linux创建进程的标准方法,调用一次,返回两次,返回值有3种类型
fork()的主要工作是寻找空闲的进程号pid,然后从父进程拷贝进程信息,例如数据段和代码段,fork()后子进程要执行的代码等。 Zygote进程是所有Android进程的母体,包括system_server和各个App进程。zygote利用fork()方法生成新进程,对于新进程A复用Zygote进程本身的资源,再加上新进程A相关的资源,构成新的应用进程A
fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的),但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。
可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们就开始分别作不同的工作,正如fork原意【分支】一样
到此system_server进程已完成了创建的所有工作,接下来开始了system_server进程的真正工作。在前面startSystemServer()方法中,zygote进程执行完forkSystemServer()后,新创建出来的system_server进程便进入handleSystemServerProcess()方法
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); //关闭父进程zygote复制而来的Socket Os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); //设置当前进程名为"system_server" } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { //执行dex优化操作 performSystemServerDexOpt(systemServerClasspath); } if (parsedArgs.invokeWith != null) { String[] args = parsedArgs.remainingArgs; if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length); } //启动应用进程 WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), null, args); } else { ClassLoader cl = null; if (systemServerClasspath != null) { 创建类加载器,并赋予当前线程 cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(cl); } //system_server故进入此分支 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } }
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit"); redirectLogStreams(); //重定向log输出 commonInit(); // 通用的一些初始化 nativeZygoteInit(); // zygote初始化 applicationInit(targetSdkVersion, argv, classLoader); // 应用初始化 } private static final void commonInit() { // 设置默认的未捕捉异常处理方法 Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); // 设置市区,中国时区为"Asia/Shanghai" TimezoneGetter.setInstance(new TimezoneGetter() { @Override public String getId() { return SystemProperties.get("persist.sys.timezone"); } }); TimeZone.setDefault(null); //重置log配置 LogManager.getLogManager().reset(); new AndroidConfig(); // 设置默认的HTTP User-agent格式( "Dalvik/1.1.0 (Linux; U; Android 6.0.1;LenovoX3c70 Build/LMY47V)"),用于 HttpURLConnection String userAgent = getDefaultUserAgent(); System.setProperty("http.agent", userAgent); // 设置socket的tag,用于网络流量统计 NetworkManagementSocketTagger.install(); } private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用 nativeSetExitWithoutCleanup(true); //设置虚拟机的内存利用率参数值为0.75 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args; try { args = new Arguments(argv); //解析参数 } catch (IllegalArgumentException ex) { return; } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); //调用startClass的static方法 main() 此处args.startClass为”com.android.server.SystemServer” invokeStaticMain(args.startClass, args.startArgs, classLoader); } private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl = Class.forName(className, true, classLoader); ... Method m; try { m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { ... } catch (SecurityException ex) { ... } //通过抛出异常,回到ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率 throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
重点看最后一个方法,通过反射获取SystemServer类的main方法参数,然后抛出MethodAndArgsCaller异常;但是抛出异常后怎么弄呢,我们知道一个方法抛异常,会一直走到调用方法,直到一个方法捕获了异常,这里就是开头讲的,在ZygoteInit.main方法捕获了异常然后去执行
public static void main(String argv[]) {
try {
if (startSystemServer) {
startSystemServer(abiList, socketName);//启动system_server
}
} catch (MethodAndArgsCaller caller) {
caller.run(); //这一步很重要,接下来会讲到
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
但是为啥没有直接在startSystemServer()或者上面的方法中直接调用SystemServer类的main方法,而是通过抛异常的方式处理呢?
我们知道,当一个函数抛出异常后,这个异常会依次传递给调用它的函数,直到这个异常被捕获,如果这个异常一直没有被处理,最终就会引起程序的崩溃。
程序都是由一个个函数组成的(除了汇编程序),c/c++/java/…等高级语言编写的应用程序,在执行的时候,他们都拥有自己的栈空间(是一种先进后出的内存区域),用于存放函数的返回地址和函数的临时数据,每调用一个函数时,就会把函数的返回地址和相关数据压入栈中,当一个函数执行完后,就会从栈中弹出,cpu会根据函数的返回地址,执行上一个调用函数的下一条指令。
所以,在抛出异常后,如果异常没有在当前的函数中捕获,那么当前的函数执行就会异常的退出,从应用程序的栈弹出,并将这个异常传递给上一个函数,直到异常被捕获处理,否则,就会引起程序的崩溃。
因此,这里通过抛异常的方式启动主要是清理应用程序栈中ZygoteInit.main以上的函数栈帧,以实现当相应的main函数退出时,能直接退出整个应用程序
public static class MethodAndArgsCaller extends Exception implements Runnable { /** 调用的方法 在上面的方法可知是main方法 */ private final Method mMethod; /** 参数列表 */ private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { Throwable cause = ex.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else if (cause instanceof Error) { throw (Error) cause; } throw new RuntimeException(ex); } } }
可以看到这里根据传递过来的参数,可知此处通过反射机制调用的是SystemServer.main()方法;到此,总算是进入到了SystemServer类的main()方法
public static void main(String[] args) { new SystemServer().run(); } private void run() { try { //如果系统时间比1970年早,那就设置为1970 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } //变更虚拟机的库文件,对于Android 6.0默认采用的是libart.so SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); //清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间 VMRuntime.getRuntime().clearGrowthLimit(); //设置内存的可能有效使用率为0.8 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // 针对部分设备依赖于运行时就产生指纹信息,因此需要在开机完成前已经定义 Build.ensureFingerprintProperty(); //访问环境变量前,需要明确地指定用户 Environment.setUserRequired(true); // Within the system server, any incoming Bundles should be defused // to avoid throwing BadParcelableException. BaseBundle.setShouldDefuse(true); //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority) BinderInternal.disableBackgroundScheduling(true); // 增加system_server中的binder线程数 BinderInternal.setMaxThreads(sMaxBinderThreads); // 创建主线程looper 在当前线程运行 android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); //初始化android_servers库 System.loadLibrary("android_servers"); //检测上次关机过程是否失败 performPendingShutdown(); //初始化系统上下文 //初始化系统上下文对象mSystemContext,并设置默认的主题,mSystemContext实际上是一个ContextImpl对象。 //调用ActivityThread.systemMain()的时候,会调用ActivityThread.attach(true),而在attach()里面,则创建了Application对象,并调用了Application.onCreate()。 createSystemContext(); //创建系统服务管理 mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } //启动各种系统服务 try { //引导服务 startBootstrapServices(); //核心服务 startCoreServices(); //其它服务 startOtherServices(); } catch (Throwable ex) { throw ex; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } //开启消息循环 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。