android开机后都发生了什么?

1. 启动流程

Android系统启动过程往细了说可以分为5步:

Loader –> Kernel –> Native –> Framework –> Application

1.1 Loader

  • Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设出代码开始执行,然后加载引导程序到RAM

  • Boot Loader: 这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数等功能

1.2 Kernel

Kernel层是指Android内核层,到这里才刚刚开始进入Android系统

  • 启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作

  • 启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖

1.3 Native

这里的Native层主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖

  • init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程
  • init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务
  • init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程

1.4 Framework

  • Zygote进程启动后,加载ZygoteInit类,注册Zygote Socket服务端套接字;加载虚拟机;加载类,加载系统资源
  • System Server进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,PowerManager等服务
  • Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务

1.5 Application

  • Zygote进程孵化出的第一个App进程是Launcher,即手机桌面APP,没错,手机桌面就是跟我们平时使用的APP一样,它也是一个应用
  • 所有APP进程都是由zygote进程fork出来的

这些层之间,有的并不能直接交流,比如Native与Kernel之间要经过系统调用才能访问,Java层和Native层需要通过JNI进行调用

严格来说,Android系统实际上是运行于Linux内核上的一系列服务进程,这些进程是维持设备正常运行的关键,而这些进程的老祖宗就是init进程

2. 启动流程(以Zygote启动流程为例)

当内核启动完成后,就会创建用户空间的第一个进程,即init进程;后面所有的进程,比如Binder机制中的ServiceManager,Zygote都是由init进程孵化出来的

对比老版本差异

在Android Q中,对该机制做了一些改变

单一的init.rc,被拆分,服务根据其二进制文件的位置(/system,/vendor,/odm)定义到对应分区的etc/init目录中,每个服务一个rc文件。与该服务相关的触发器、操作等也定义在同一rc文件中。

1
2
3
/system/etc/init,包含系统核心服务的定义,如SurfaceFlinger、MediaServer、Logcatd等。
/vendor/etc/init, SOC厂商针对SOC核心功能定义的一些服务。比如高通、MTK某一款SOC的相关的服务。
/odm/etc/init,OEM/ODM厂商如小米、华为、OPP其产品所使用的外设以及差异化功能相关的服务。

下图为Android Q 中定义的所有服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
./recovery/root/init.rc
./recovery/root/ueventd.rc
./recovery/root/init.recovery.mt6762.rc
./recovery/root/init.recovery.mt6765.rc
./vendor/ueventd.rc
./vendor/etc/init/init.wmt_drv.rc
./vendor/etc/init/init.volte_imsm_93.rc
./vendor/etc/init/mtk_agpsd_p.rc
./vendor/etc/init/bootperf.rc
./vendor/etc/init/audiocmdservice_atci.rc
./vendor/etc/init/android.hardware.graphics.composer@2.1-service.rc
./vendor/etc/init/vendor.mediatek.hardware.gpu@1.0-service.rc
./vendor/etc/init/init.volte_stack.rc
./vendor/etc/init/init_connectivity.rc
./vendor/etc/init/init.fmradio_drv.rc
./vendor/etc/init/netdagent.rc
./vendor/etc/init/atcid_eng.rc
./vendor/etc/init/init.vtservice_hidl.rc
./vendor/etc/init/mtkrild.rc
./vendor/etc/init/android.hardware.health@2.0-service.rc
./vendor/etc/init/init.wfca.rc
./vendor/etc/init/modemdbfilter_service.rc
./vendor/etc/init/init.bt_drv.rc
./vendor/etc/init/init.gps_drv.rc
./vendor/etc/init/aee_aedv64.rc
./vendor/etc/init/android.hardware.secure_element@1.0-service-mediatek.rc
./vendor/etc/init/android.hardware.drm@1.2-service.clearkey.rc
./vendor/etc/init/vendor.mediatek.hardware.log@1.0-service.rc
./vendor/etc/init/init.thermal_manager.rc
./vendor/etc/init/init.bip.rc
./vendor/etc/init/init.cccimdinit.rc
./vendor/etc/init/md_monitor.rc
./vendor/etc/init/muxreport.rc
./vendor/etc/init/android.hardware.drm@1.0-service.rc
./vendor/etc/init/init.wlan_drv.rc
./vendor/etc/init/android.hardware.drm@1.2-service.widevine.rc
./vendor/etc/init/wlan_assistant.rc
./vendor/etc/init/camerahalserver.rc
./vendor/etc/init/atci_service.rc
./vendor/etc/init/android.hardware.cas@1.1-service.rc
./vendor/etc/init/ipsec_mon.rc
./vendor/etc/init/android.hardware.thermal@1.0-service.rc
./vendor/etc/init/android.hardware.gatekeeper@1.0-service.rc
./vendor/etc/init/android.hardware.keymaster@4.0-service.rc
./vendor/etc/init/init.thermalloadalgod.rc
./vendor/etc/init/android.hardware.graphics.allocator@2.0-service.rc
./vendor/etc/init/vendor.mediatek.hardware.mtkpower@1.0-init.rc
./vendor/etc/init/lbs_hidl_service.rc
./vendor/etc/init/android.hardware.sensors@2.0-service-mediatek.rc
./vendor/etc/init/hostapd.android.rc
./vendor/etc/init/init.thermal.rc
./vendor/etc/init/fuelgauged_nvram_init.rc
./vendor/etc/init/em_hidl_eng.rc
./vendor/etc/init/vendor.mediatek.hardware.mtkpower@1.0-service.rc
./vendor/etc/init/init.cccirpcd.rc
./vendor/etc/init/init.volte_md_status.rc
./vendor/etc/init/android.hardware.light@2.0-service-mediatek.rc
./vendor/etc/init/aee_aedv.rc
./vendor/etc/init/init.cccifsd.rc
./vendor/etc/init/gsm0710muxd.rc
./vendor/etc/init/loghidlvendorservice.rc
./vendor/etc/init/fuelgauged_init.rc
./vendor/etc/init/android.hardware.wifi@1.0-service-lazy-mediatek.rc
./vendor/etc/init/android.hardware.bluetooth@1.0-service-mediatek.rc
./vendor/etc/init/ppl_agent.rc
./vendor/etc/init/hw/init.project.rc
./vendor/etc/init/hw/init.sensor_1_0.rc
./vendor/etc/init/hw/init.mt6765.rc
./vendor/etc/init/hw/meta_init.connectivity.rc
./vendor/etc/init/hw/meta_init.project.rc
./vendor/etc/init/hw/multi_init.rc
./vendor/etc/init/hw/factory_init.project.rc
./vendor/etc/init/hw/factory_init.rc
./vendor/etc/init/hw/init.mt6762.rc
./vendor/etc/init/hw/init.mt6765.usb.rc
./vendor/etc/init/hw/factory_init.connectivity.rc
./vendor/etc/init/hw/init.connectivity.rc
./vendor/etc/init/hw/init.aee.rc
./vendor/etc/init/hw/init.modem.rc
./vendor/etc/init/hw/init.ago.rc
./vendor/etc/init/hw/meta_init.modem.rc
./vendor/etc/init/hw/meta_init.rc
./vendor/etc/init/init.md_apps.rc
./vendor/etc/init/android.hardware.media.omx@1.0-service.rc
./vendor/etc/init/init.volte_ua.rc
./vendor/etc/init/nvram_daemon.rc
./vendor/etc/init/init.wod.rc
./vendor/etc/init/vendor.mediatek.hardware.nvram@1.1-sevice.rc
./vendor/etc/init/android.hardware.memtrack@1.0-service.rc
./vendor/etc/init/android.hardware.configstore@1.1-service.rc
./vendor/etc/init/android.hardware.usb@1.1-service-mediatek.rc
./vendor/etc/init/vendor.mediatek.hardware.mtkcodecservice@1.1-service.rc
./vendor/etc/init/init.volte_imcb.rc
./vendor/etc/init/android.hardware.audio@5.0-service-mediatek.rc
./vendor/etc/init/android.hardware.vibrator@1.0-service.rc
./vendor/etc/init/vendor.mediatek.hardware.mms@1.3-service.rc
./vendor/etc/init/vndservicemanager.rc
./vendor/etc/init/android.hardware.gnss@2.0-service-mediatek.rc
./vendor/etc/init/vendor.mediatek.hardware.pq@2.2-service.rc
./system/apex/com.android.media.swcodec/etc/init.rc
./system/etc/init/mdlogger.rc
./system/etc/init/atrace.rc
./system/etc/init/mediaextractor.rc
./system/etc/init/surfaceflinger.rc
./system/etc/init/ashmemd.rc
./system/etc/init/android.system.suspend@1.0-service.rc
./system/etc/init/uncrypt.rc
./system/etc/init/camerapostalgo.rc
./system/etc/init/bootlogoupdater.rc
./system/etc/init/art_apex_boot_integrity.rc
./system/etc/init/usbd.rc
./system/etc/init/modemdbfilter_client.rc
./system/etc/init/atci_service_sys.rc
./system/etc/init/drmserver.rc
./system/etc/init/recovery-persist.rc
./system/etc/init/aee_aed64.rc
./system/etc/init/keystore.rc
./system/etc/init/wait_for_keymaster.rc
./system/etc/init/mobile_log_d.rc
./system/etc/init/mediaserver.rc
./system/etc/init/hwservicemanager.rc
./system/etc/init/init-debug.rc
./system/etc/init/gpuservice.rc
./system/etc/init/logd.rc
./system/etc/init/incidentd.rc
./system/etc/init/servicemanager.rc
./system/etc/init/lpdumpd.rc
./system/etc/init/idmap2d.rc
./system/etc/init/bootstat.rc
./system/etc/init/blank_screen.rc
./system/etc/init/bootstat-debug.rc
./system/etc/init/storaged.rc
./system/etc/init/netd.rc
./system/etc/init/mediametrics.rc
./system/etc/init/mediadrmserver.rc
./system/etc/init/wificond.rc
./system/etc/init/vdc.rc
./system/etc/init/cameraserver.rc
./system/etc/init/gsid.rc
./system/etc/init/consyslogger.rc
./system/etc/init/logtagd.rc
./system/etc/init/malloc_debug_option.rc
./system/etc/init/bootanim.rc
./system/etc/init/logcatd.rc
./system/etc/init/batterywarning.rc
./system/etc/init/statsd.rc
./system/etc/init/perfetto.rc
./system/etc/init/init.connectivity.rc
./system/etc/init/flags_health_check.rc
./system/etc/init/mtpd.rc
./system/etc/init/init.thermald.rc
./system/etc/init/mdnsd.rc
./system/etc/init/duraspeed.rc
./system/etc/init/emdlogger3.rc
./system/etc/init/audioserver.rc
./system/etc/init/terserver.rc
./system/etc/init/heapprofd.rc
./system/etc/init/netdiag.rc
./system/etc/init/bpfloader.rc
./system/etc/init/init.vtservice.rc
./system/etc/init/hw/init.aee.rc
./system/etc/init/hw/vendor_init_as_system.rc
./system/etc/init/emdlogger5.rc
./system/etc/init/iorapd.rc
./system/etc/init/wifi-events.rc
./system/etc/init/tombstoned.rc
./system/etc/init/kpoc_charger.rc
./system/etc/init/apexd.rc
./system/etc/init/traceur.rc
./system/etc/init/android.hidl.allocator@1.0-service.rc
./system/etc/init/gatekeeperd.rc
./system/etc/init/atrace_userdebug.rc
./system/etc/init/lmkd.rc
./system/etc/init/rss_hwm_reset.rc
./system/etc/init/installd.rc
./system/etc/init/racoon.rc
./system/etc/init/emdlogger2.rc
./system/etc/init/emdlogger1.rc
./system/etc/init/em_svr.rc
./system/etc/init/dumpstate.rc
./system/etc/init/aee_aed.rc
./system/etc/init/vold.rc
./root/init.rc
./root/init.zygote32.rc
./root/init.environ.rc
./root/ueventd.rc
./root/init.zygote64_32.rc
./root/init.preload.rc
./root/init.usb.configfs.rc
./root/init.usb.rc

2.1 启动

当init进程启动后会调用/system/core/init/main.cpp的main()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
__asan_set_error_report_callback(AsanReportCallback);
#endif

if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv); //ueventd.cpp入口函数,初始化uevent
}

if (argc > 1) {
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap function_map;

return SubcontextMain(argc, argv, &function_map);
}

if (!strcmp(argv[1], "selinux_setup")) {
// This function initializes SELinux then execs init to run in the init SELinux context.
return SetupSelinux(argv); //对SELinux进行初始化,并通过execs的系统调用开启init进程
}

if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv); //第二阶段 init.cpp入口函数
}
}

return FirstStageMain(argc, argv); //第一阶段
}

注:Android10中并不只是调用init::main,而是把部分流程性的判断放到的mian.cpp中来做,如果直接去找init.cpp中的main函数,其实是找不到入口的

2.2 一阶段启动

第一阶段init位于 system/core/init/first_stage_init.cpp的FirstStageMain方法,主要是设置umask,部分代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int FirstStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}

boot_clock::time_point start_time = boot_clock::now();

std::vector<std::pair<std::string, int>> errors;
#define CHECKCALL(x) \
if (x != 0) errors.emplace_back(#x " failed", errno);

// Clear the umask.
umask(0);

CHECKCALL(clearenv());
CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));
// Get the basic filesystem setup we need put together in the initramdisk
// on / and then we'll let the rc file figure out the rest.
CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
CHECKCALL(mkdir("/dev/pts", 0755));
CHECKCALL(mkdir("/dev/socket", 0755));
CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));

....

return 1;
}

2.3 二阶段启动

第二阶段init位于system/core/init/init.cpp的SecondStageMain方法,该部分负责加载.rc文件,部分代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
int SecondStageMain(int argc, char** argv) {
/*
*init crash时重启引导加载程序
*这个函数主要作用将各种信号量,如SIGABRT,SIGBUS等的行为设置为SA_RESTART,一旦监听到这些信号即执行重启系统
*/
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}

//把标准输入、标准输出和标准错误重定向到空设备文件"/dev/null"
SetStdioToDevNull(argv);
//在/dev目录下挂载好 tmpfs 以及 kmsg
//这样就可以初始化 /kernel Log 系统,供用户打印log
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";

// 01. 创建进程会话密钥并初始化属性系统
keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);

//创建 /dev/.booting 文件,就是个标记,表示booting进行中
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));

// 初始化属性系统,并从指定文件读取属性
property_init();

/*
* 1.如果参数同时从命令行和DT传过来,DT的优先级总是大于命令行的
* 2.DT即device-tree,中文意思是设备树,这里面记录自己的硬件配置和系统运行参数,
*/
process_kernel_dt(); // 处理 DT属性
process_kernel_cmdline(); // 处理命令行属性

// 处理一些其他的属性
export_kernel_boot_props();

// Make the time that init started available for bootstat to log.
property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));

// Set libavb version for Framework-only OTA match in Treble build.
const char* avb_version = getenv("INIT_AVB_VERSION");
if (avb_version) property_set("ro.boot.avb_version", avb_version);

// See if need to load debug props to allow adb root, when the device is unlocked.
const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");
if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
load_debug_prop = "true"s == force_debuggable_env;
}

// 基于cmdline设置memcg属性
bool memcg_enabled = android::base::GetBoolProperty("ro.boot.memcg",false);
if (memcg_enabled) {
// root memory control cgroup
mkdir("/dev/memcg", 0700);
chown("/dev/memcg",AID_ROOT,AID_SYSTEM);
mount("none", "/dev/memcg", "cgroup", 0, "memory");
// app mem cgroups, used by activity manager, lmkd and zygote
mkdir("/dev/memcg/apps/",0755);
chown("/dev/memcg/apps/",AID_SYSTEM,AID_SYSTEM);
mkdir("/dev/memcg/system",0550);
chown("/dev/memcg/system",AID_SYSTEM,AID_SYSTEM);
}

// 清空这些环境变量,之前已经存到了系统属性中去了
unsetenv("INIT_STARTED_AT");
unsetenv("INIT_SELINUX_TOOK");
unsetenv("INIT_AVB_VERSION");
unsetenv("INIT_FORCE_DEBUGGABLE");

// Now set up SELinux for second stage.
SelinuxSetupKernelLogging();
SelabelInitialize();

/*
* 02. 进行SELinux第二阶段并恢复一些文件安全上下文
* 恢复相关文件的安全上下文,因为这些文件是在SELinux安全机制初始化前创建的,
* 所以需要重新恢复上下文
*/
SelinuxRestoreContext();

/*
* 03. 新建epoll并初始化子进程终止信号处理函数
* 创建epoll实例,并返回epoll的文件描述符
*/
Epoll epoll;
if (auto result = epoll.Open(); !result) {
PLOG(FATAL) << result.error();
}

/*
*主要是创建handler处理子进程终止信号,注册一个signal到epoll进行监听
*进行子继承处理
*/
InstallSignalFdHandler(&epoll);

// 进行默认属性配置相关的工作
property_load_boot_defaults(load_debug_prop);
UmountDebugRamdisk();
fs_mgr_vendor_overlay_mount_all();
export_oem_lock_status();

/*
*04. 设置其他系统属性并开启系统属性服务
*/
StartPropertyService(&epoll);
MountHandler mount_handler(&epoll);

//为USB存储设置udc Contorller, sys/class/udc
set_usb_controller();

// 匹配命令和函数之间的对应关系
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);

if (!SetupMountNamespaces()) {
PLOG(FATAL) << "SetupMountNamespaces failed";
}

// 初始化文件上下文
subcontexts = InitializeSubcontexts();

/*
*05 解析init.rc等文件,建立rc文件的action 、service,启动其他进程
*/
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();

//加载.rc文件
LoadBootScripts(am, sm);

// Turning this on and letting the INFO logging be discarded adds 0.2s to
// Nexus 9 boot time, so it's disabled by default.
if (false) DumpState();

// 当GSI脚本running时,确保GSI状态可用.
if (android::gsi::IsGsiRunning()) {
property_set("ro.gsid.image_running", "1");
} else {
property_set("ro.gsid.image_running", "0");
}


am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");

// 执行rc文件中触发器为 on early-init 的语句
am.QueueEventTrigger("early-init");

// 等冷插拔设备初始化完成
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");

// 开始查询来自 /dev的 action
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");

// 设备组合键的初始化操作
Keychords keychords;
am.QueueBuiltinAction(
[&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> {
for (const auto& svc : ServiceList::GetInstance()) {
keychords.Register(svc->keycodes());
}
keychords.Start(&epoll, HandleKeychord);
return Success();
},
"KeychordInit");

//在屏幕上显示Android 静态LOGO
am.QueueBuiltinAction(console_init_action, "console_init");

// 执行rc文件中触发器为on init的语句
am.QueueEventTrigger("init");

// Starting the BoringSSL self test, for NIAP certification compliance.
am.QueueBuiltinAction(StartBoringSslSelfTest, "StartBoringSslSelfTest");

// Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
// wasn't ready immediately after wait_for_coldboot_done
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");

// Initialize binder before bringing up other system services
am.QueueBuiltinAction(InitBinder, "InitBinder");

// 当设备处于充电模式时,不需要mount文件系统或者启动系统服务
// 充电模式下,将charger假如执行队列,否则把late-init假如执行队列
std::string bootmode = GetProperty("ro.bootmode", "");
if (bootmode == "charger") {
am.QueueEventTrigger("charger");
} else {
am.QueueEventTrigger("late-init");
}

// 基于属性当前状态 运行所有的属性触发器.
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");

while (true) {
// By default, sleep until something happens.
auto epoll_timeout = std::optional<std::chrono::milliseconds>{};

if (do_shutdown && !shutting_down) {
do_shutdown = false;
if (HandlePowerctlMessage(shutdown_command)) {
shutting_down = true;
}
}

//依次执行每个action中携带command对应的执行函数
if (!(waiting_for_prop || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || Service::is_exec_service_running())) {
if (!shutting_down) {
auto next_process_action_time = HandleProcessActions();

// If there's a process that needs restarting, wake up in time for that.
if (next_process_action_time) {
epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
*next_process_action_time - boot_clock::now());
if (*epoll_timeout < 0ms) epoll_timeout = 0ms;
}
}

// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) epoll_timeout = 0ms;
}

// 循环等待事件发生
if (auto result = epoll.Wait(epoll_timeout); !result) {
LOG(ERROR) << result.error();
}
}

return 0;
}


LoadBootScripts方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);

std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
if (!parser.ParseConfig("/product_services/etc/init")) {
late_import_paths.emplace_back("/product_services/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}

2.4 三阶段启动init.rc

当属性服务建立完成后,init的自身功能基本就告一段落,接下来需要来启动其他的进程。但是init进程如何其他其他进程呢?其他进程都是一个二进制文件,我们可以直接通过exec的命令方式来启动,例如 ./system/bin/init second_stage,来启动init进程的第二阶段。但是Android系统有那么多的Native进程,如果都通过传exec在代码中一个个的来执行进程,那无疑是一个灾难性的设计。

在这个基础上Android推出了一个init.rc的机制,即类似通过读取配置文件的方式,来启动不同的进程。接下来我们就来看看init.rc是如何工作的。

init.rc是一个配置文件,内部由Android初始化语言编写(Android Init Language)编写的脚本。

init.rc在手机的目录:./init.rc

启动zygote的.rc文件位于system/core/rootdir/init.rc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

.....

//根据系统ro.zygote属性来启动对应位数(32/64)进程
//ro.zygote 为zygote32/zygote32_64/zygote64_32/zygote64
import /init.${ro.zygote}.rc


on zygote-start && property:ro.crypto.state=unencrypted

start netd //启动网络相关守护进程
start zygote //启动zygote
start zygote_secondary //启动zygote_secondary
.....

android10 ro.zygote系统默认为zygote64_32,当 ro.zygote为zygote32

import /init.zygote32.rc,对应rc文件为 system/core/rootdir/init.zygote32.rc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//通过system/bin/app_process命令启动zygote
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system //注册socks服务
socket usap_pool_primary 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

当 ro.zygote 为zygote64_32

import /init.zygote64_32.rc,对应rc文件为 system/core/rootdir/init.zygote64_32.rc,为了兼容32位应用会同时开启64位和32位两个zygote进程,且优先使用64位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//通过system/bin/app_process64命令启动zygote
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system //注册socks服务
socket usap_pool_primary 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

//通过system/bin/app_process32命令启动zygote
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system //注册socks服务
socket usap_pool_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重启

servicemanager进程被杀
surfaceflinger进程被杀
Zygote进程自己被杀
system_server进程被杀

2.5 运行/system/bin/app_processXX

接下来看看zygote启动过程,zygote对应的可执行文件就是/system/bin/app_processXX,也就是说系统启动时会执行到这个可执行文件的main()函数里

源码位于 frameworks/base/cmds/app_process/app_main.cpp,部分代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
int main(int argc, char* const argv[])
{
......

// 创建 AppRuntime的成员变量

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; // Skip --.
break;
}
runtime.addOption(strdup(argv[i]));
}

// 解析运行时参数,赋值zygote和startSystemServer

bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;

++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}

.......

if (zygote) {
// 调用 ZygoteInit#main()
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.");
return 10;
}


上述代码,首先创建了一个AppRuntime的局部成员变量,然后对入参进行了解析,根据对init.zygote64_32.rc传入参数的分析,这里的zygote变量和startSystemServer的值均为true,因此在最后调用AppRuntime#start()函数时走了,而AppRuntime继承了AndroidRuntime,而子类里没有start方法,所以此处调用了AndroidRuntime::start()

2.6 AndroidRuntime::start()

AndroidRuntime类位于frameworks/base/core/jni/AndroidRuntime.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{

/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL); //加载libart.so、导出三个主要jni方法(JNI_GetDefaultJavaVMInitArgs、JNI_CreateJavaVM、JNI_GetCreatedJavaVMs)
JNIEnv* env;
// 虚拟机创建,主要篇幅是关于虚拟机参数的设置
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);

// JNI方法注册
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}

jclass stringClass;
jobjectArray strArray;
jstring classNameStr;

//等价 strArray= new String[options.size() + 1];
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);

//等价 strArray[0] = "com.android.internal.os.ZygoteInit"
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
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());
assert(optionsStr != NULL);
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) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);

} else {
//找到这个类后就继续找成员函数main方法的Mehtod ID
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);

} else {
// 通过反射调用ZygoteInit.main()方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);

}
}
//释放相应对象的内存空间
free(slashClassName);

.....
}

该函数启动了 Android 系统运行时库,其中它主要做了三件事:

  1. 调用startVmVM()函数启动虚拟机
  2. 调用startReg()函数注册 Android 的 Java 方法,其实在这里就是 JNI 方法
  3. 反射调用 Java 类com.android.internal.os.ZygoteInit#main()方法,并把 fork zygote进程时的参数传入用来辅助初始化zygote进程

2.7 AndroidRuntime::startVm()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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;
}
}

2.8 AndroidRuntime::startReg()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}

2.9 进入java世界,com.android.internal.os.ZygoteInit#main()

源码位于frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public static void main(String argv[]) {
// 标记Zygote开始初始化,并Hook确保不创建其他线程
ZygoteHooks.startZygoteNoThreadCreation();

try {
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
//开启DDMS功能
RuntimeInit.enableDdms();
// Start profiling the zygote initialization.
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]);
}
}

if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
//为Zygote注册socket
registerZygoteSocket(socketName);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
// 预加载类和资源
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();

// Do an initial gc to clean up after startup
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
gcAndFinalize();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);

// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
// 停止Hook不创建其他线程,也就是说允许创建其他线程
ZygoteHooks.stopZygoteNoThreadCreation();
// 这里一定是true,启动SystemServer
if (startSystemServer) {
startSystemServer(abiList, socketName);
}

Log.i(TAG, "Accepting command socket connections");
// 运行zygote进程的select循环
runSelectLoop(abiList);

closeServerSocket();
} catch (MethodAndArgsCaller caller) {
//捕获异常,并运行run方法
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}

在这个初始化过程中,做了不少准备工作,更加详细的过程请阅读上述代码注释和源码,我们这里总结以下我们需要着重关注的几件事:

  1. 调用ZygoteServer#registerServerSocket()方法创建一个名为zygote的 Socket 资源
  2. 调用preload预加载资源
  3. 调用ZygoteInit#starSystemServer()方法启动system_server进程
  4. 调用ZygoteInit#runSelectLoop()方法循环接受 Socket 连接,在这里开始和 AMS 搭上边,其实这里就是循环等待 AMS 的连接和命令,更加详细的过程在下文中分析。

2.10 ZygoteInit.registerZygoteSocket()

Socket 是 IPC 通信的一种方式,该 Socket 资源在后期被用在和 AMS 等服务进行进程间通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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);
//创建Socket的本地服务端
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}

2.11 ZygoteInit.preload()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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加载到内存的

2.11 ZygoteInit.startSystemServer()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server", // 指定进程名字 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);


// 从zygote进程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创建完成

2.12 Zygote.forkSystemServer()

源码位于frameworks/base/core/java/com/android/internal/os/Zygote.java

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
// Enable tracing as soon as we enter the system_server.
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方法的映射关系,所以接下来进入如下方法
com_android_internal_os_Zygote.nativeForkSystemServer

2.13 com_android_internal_os_Zygote.nativeForkSystemServer()

源码位于 frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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, __LINE__, "System server process has died. Restarting Zygote!");
}
}
return pid;
}

当system_server进程创建失败时,将会重启zygote进程。这里需要注意,对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,system_server的父进程,一般来说64位系统其父进程是zygote64进程

  • 当kill system_server进程后,只重启zygote64和system_server,不重启zygote;
  • 当kill zygote64进程后,只重启zygote64和system_server,也不重启zygote;
  • 当kill zygote进程,则重启zygote、zygote64以及system_server。

2.14 com_android_internal_os_Zygote.ForkAndSpecializeCommon()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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;
}

到此system_server进程已完成了创建的所有工作,接下来开始了system_server进程的真正工作。在前面startSystemServer()方法中,zygote进程执行完forkSystemServer()后,新创建出来的system_server进程便进入handleSystemServerProcess()方法

2.15 ZygoteInit.handleSystemServerProcess()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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);
}
}

2.16 RuntimeInit.zygoteInit()

源码位于frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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方法捕获了异常然后去执行

2.17 ZygoteInit.main()

1
2
3
4
5
6
7
8
9
10
11
12
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函数退出时,能直接退出整个应用程序

2.18 ZygoteInit.MethodAndArgsCaller.run()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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()方法

2.19 SystemServer.main()

源码位于 frameworks/base/services/java/com/android/server/SystemServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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");
}

至此system_server已启动完成,大致流程如下:

  1. zygote进程通过Zygote.forkSystemServer —> fork.fork()创建system server进程
  2. 调用ZygoteInit.handleSystemServerProcess方法设置当前进程名为”system_server”,执行dex优化操作,一些属性的初始化,设置binder线程
  3. 通过抛出MethodAndArgsCaller异常,回到ZygoteInit.main(),在try catch中执行MethodAndArgsCaller.run;在这里通过反射执行SystemServer.main()方法
  4. 在SystemServer.run方法中做一些设置,比如初始化系统上下文 ,创建SystemServiceManager,启动引导服务,启动核心服务,启动其他服务
  5. 最后调用Looper.loop(),不断的从消息队列取出消息处理(Looper#loop()方法中调用的是MessageQueue#next(),该方法中使用死循环 + Linuxepoll机制持续运行程序)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
system server进程和zygote进程可以说是Android世界中的两大最重要的进程,离开其中之一基本上系统就玩完了;基本上在Java Framework中的大多数服务都是在system server进程中一个线程的方式存在的,如下:

EntropyService 提供伪随机数
PowerManagerService 电源管理服务
ActivityManagerService 最核心的服务之一,管理 四大组件
TelephonyRegistry 通过该服务注册电话模块的事件响应,比如重启、关闭、启动等
PackageManagerService 程序包管理服务
AccountManagerService 账户管理服务,是指联系人账户,而不是 Linux 系统的账户
ContentService ContentProvider 服务,提供跨进程数据交换
BatteryService 电池管理服务
LightsService 自然光强度感应传感器服务
VibratorService 震动器服务
AlarmManagerService 定时器管理服务,提供定时提醒服务
WindowManagerService Framework 最核心的服务之一,负责窗口管理
BluetoothService 蓝牙服务
DevicePolicyManagerService 提供一些系统级别的设置及属性
StatusBarManagerService 状态栏管理服务
ClipboardService 系统剪切板服务
InputMethodManagerService 输入法管理服务
NetStatService 网络状态服务
NetworkManagementService 网络管理服务
ConnectivityService 网络连接管理服务
ThrottleService 暂不清楚其作用
AccessibilityManagerService 辅助管理程序截获所有的用户输入,并根据这些输入给用户一些额外的反馈,起到辅助的效果
MountService 挂载服务,可通过该服务调用 Linux 层面的 mount 程序
NotificationManagerService 通知栏管理服务, Android 中的通知栏和状态栏在一起,只是界面上前者在左边,后者在右边
DeviceStorageMonitorService 磁盘空间状态检测服务
LocationManagerService 地理位置服务
SearchManagerService 搜索管理服务
DropBoxManagerService 通过该服务访问 Linux 层面的 Dropbox 程序
WallpaperManagerService 墙纸管理服务,墙纸不等同于桌面背景,在 View 系统内部,墙纸可以作为任何窗口的背景
AudioService 音频管理服务
BackupManagerService 系统备份服务
AppWidgetService Widget 服务
RecognitionManagerService 身份识别服务
DiskStatsService 磁盘统计服务

2.20 ZygoteInit.runSelectLoop()

在2.9中ZygoteInit.main()方法开启system_server后,执行runSelectLoop()方法,进入循环监听事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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中移除该文件描述符
}
}
}
}
}

2.21 ZygoteInit.acceptCommandPeer

1
2
3
4
5
6
7
private static ZygoteConnection acceptCommandPeer(String abiList) {
try {
return new ZygoteConnection(sServerSocket.accept(), abiList);
} catch (IOException ex) {
...
}
}

2.22 ZygoteConnection.runOnce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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);
}
}

至此Zygote启动完成,开启循环
接收客户端发送过来的connect()操作,Zygote作为服务端执行accept()操作。 再后面客户端调用write()写数据,Zygote进程调用read()读数据。

没有连接请求时会进入休眠状态,当有创建新进程的连接请求时,唤醒Zygote进程,创建Socket通道ZygoteConnection,然后执行ZygoteConnection的runOnce()方法。

Zygote启动流程如下:

  1. 解析init.zygote64_32.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法
  2. 调用AndroidRuntime的startVM()方法创建虚拟机,再调用startReg()注册JNI函数
  3. 通过JNI方式调用ZygoteInit.main(),第一次进入Java世界
  4. registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求
  5. preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率
  6. 通过startSystemServer(),fork得力帮手system_server进程,也是Java Framework的运行载体
  7. 调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作

3. Zygote进程是如何fork一个APP进程的

创建一个线程大家肯定非常熟悉了,继承Thread,实现Runnable接口或者Callable接口;但是线程没有独立的地址空间,而是与所在进程共享内存,其实从Linux角度看,进程线程都是一个task_struct结构体,除了是否共享资源外,并没有其他本质的区别。

但是创建进程可能就没有那么熟悉了,每个APP可能运行在一个进程,也可能在多个进程,这些进程拥有自己独立的资源;然而这些进程都是由Zygote进程fork出来的,再往前一步其实是system server进程使用LocalSocket去通知zygote进程,然后zygote去fork一个子进程,也就是APP进程(更往前一步就是APP进程使用Binder机制去通知system server进程中的ActivityManagerService),注意这里是子进程,不是子线程

大体流程:

  1. app_process作为zygote server通过local socket处理进程创建请求,zygote server是在ZygoteInit.main函数里调用ZygoteInit.runSelectLoop监听。

  2. 接收到zygote client的fork请求之后,调用ZygoteConnection.runOnce,调用Zygote.forkAndSpecialize创建新进程

  3. 进程创建之后,由ZygoteConnection.handleParentProc来初始化进程,最终会调用ActivityThread.main函数

  4. ActivityThread.main -> ActivityThread.attach -> ActivityThread.bindApplication -> Activity.handleBindApplication,handleBindApplication会初始化BaseDexClassLoader。

  5. 类的加载经过了ClassLoader.loadClass->BaseDexClassLoader.findClass->DexPathList.findClass->DexFile.loadClassBinaryName->DexFile.defineClassNative->DexFile_defineClassNative(art/runtime/native/dalvik_system_DexFile.cc)
    这个初始化过程,art和dalvik都是一样的。art的DexFile_defineClassNative由ClassLinker的DefineClass来加载类。

3.1 APP进程创建流程

  1. 不管从桌面启动应用还是应用内启动其它应用,如果这个应用所在进程不存在的话,都需要发起进程通过Binder机制告诉system server进程的AMS
  2. system server进程的AMS调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求
  3. 在zygote进程的ZygoteInit.main方法中,有一个runSelectLoop循环体,通过acceptCommandPeer方法获取链接过来的客户端,再通过runOnce方法去创建进程
  4. 新的进程执行handleChildProc方法,最后通过反射调用ActivityThread.main()方法,这样一个新的APP进程就创建完成了

3.2 APP启动第三方应用

3.2.1 startActivity

当你在桌面启动一个应用或者在一个APP内启动一个应用,本质都是一样的,因为Android手机桌面其实就是一个APP(这点可参考Android之Activity启动流程源码深入解析),两种方式经过层层调用之后都会走到ActivityStackSupervisor.startSpecificActivityLocked方法,判断如果对方进程不存在,就需要去创建一个进程

3.2.2 startService

调用startService启动一个服务,该方法经过层层调用最终会走到ActiveServices.bringUpServiceLocked方法,如果判断对方进程不存在也会去创建一个新进程

3.2.3 sendBroadcast

调用sendBroadcast方法去发送一个广播,经过层层调用后走到BroadcastQueue.processNextBroadcast方法,也会判断BroadcastReceiver所在进程不存在就需要去创建进程

3.2.4 ContentResolver.query

在ContentProvider的处理过程中,ContentResolver.query方法经过层层调用会走到ActivityManagerService.getContentProviderImpl方法,判断ContentProvider所在的进程不存在就会创建新进程

3.3 System Server请求创建进程

ActivityManagerService简称为AMS

上述四种途径最终都会走到AMS.startProcessLocked()方法

3.3.1 AMS.startProcessLocked()

源码位于frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
//不处于孤立进程
if (!isolated) {
//根据进程名和进程uid获取进程对应的ProcessRecord
//ProcessRecord封装了正在运行的进程的完整信息
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkTime(startTime, "startProcess: after getProcessRecord");

if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
// 如果当前进程处于后台进程,就判断是否在Bad进程列表
if (mAppErrors.isBadProcessLocked(info)) {
return null;
}
} else {
// 如果用户明确启动该进程,则清除其crash计数,保证其不处于Bad进程列表,直到下次再弹出crash框
mAppErrors.resetProcessCrashTimeLocked(info);
if (mAppErrors.isBadProcessLocked(info)) {
EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
UserHandle.getUserId(info.uid), info.uid,
info.processName);
mAppErrors.clearBadProcessLocked(info);
if (app != null) {
app.bad = false;
}
}
}
} else {
// 如果是孤立进程,就没办法重用已存在的进程
app = null;
}

......

//当ProcessRecord已经存在;
//并且调用者不认为进程已经死亡,或者没有thread对象依附到该进程,这样我们就知道他不会crash;
//该进程已经分配了pid,说明它正在启动或正在运行
//这些情况下我们不需要做什么,直接返回
if (app != null && app.pid > 0) {
if ((!knownToBeDead && !app.killed) || app.thread == null) {
//我们已经启动了这个app,或者正在等待它启动(分配了pid但是没有thread依附),就keep it
// 如果这是该进程中的一个新的package,那就添加到package列表
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, "startProcess: done, added package to proc");
return app;
}

// 如果ProcessRecord已经attach到先前的进程,那就清除它
checkTime(startTime, "startProcess: bad proc running, killing");
killProcessGroup(app.uid, app.pid);
handleAppDiedLocked(app, true, true);
checkTime(startTime, "startProcess: done killing old proc");
}

String hostingNameStr = hostingName != null
? hostingName.flattenToShortString() : null;

if (app == null) {
checkTime(startTime, "startProcess: creating new process record");
// 创建新的Process Record对象
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
if (app == null) {
return null;
}
app.crashHandler = crashHandler;
checkTime(startTime, "startProcess: done creating new process record");
} else {
// 如果这是该进程中的一个新的package,那就添加到package列表
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, "startProcess: added package to existing proc");
}

// 如果系统还没有准备就绪,那就暂停该进程启动,将当前进程加入到mProcessesOnHold,直到准备就绪
if (!mProcessesReady
&& !isAllowedWhileBooting(info)
&& !allowWhileBooting) {
if (!mProcessesOnHold.contains(app)) {
mProcessesOnHold.add(app);
}
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
"System not ready, putting on hold: " + app);
checkTime(startTime, "startProcess: returning with proc on hold");
return app;
}

checkTime(startTime, "startProcess: stepping in to startProcess");
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, "startProcess: done starting proc!");
return (app.pid != 0) ? app : null;
}

经过上面重重判断后决定需要创建进程,继续走到startProcessLocked方法,这个方法在AMS里有4个重载的方法

其中的hostingType参数有”activity”,”service”,”broadcast”,”content provider”四个值
hostingNameStr数据类型为ComponentName,封装了组件的包名和自己的路径

3.3.2 继续调用AMS.startProcessLocked()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
//当app的pid大于0且不是当前进程的pid,则从mPidsSelfLocked中移除该app.pid
if (app.pid > 0 && app.pid != MY_PID) {
checkTime(startTime, "startProcess: removing from pids map");
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
checkTime(startTime, "startProcess: done removing from pids map");
app.setPid(0);
}

//从mProcessesOnHold移除该app
mProcessesOnHold.remove(app);

checkTime(startTime, "startProcess: starting to update cpu stats");
updateCpuStats();
checkTime(startTime, "startProcess: done updating cpu stats");

try {
try {
final int userId = UserHandle.getUserId(app.uid);
AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
//当前package已被冻结,则抛出异常
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}

int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
int[] permGids = null;
try {
checkTime(startTime, "startProcess: getting gids from package manager");
//通过Package Manager获取gids
final IPackageManager pm = AppGlobals.getPackageManager();
permGids = pm.getPackageGids(app.info.packageName,
MATCH_DEBUG_TRIAGED_MISSING, app.userId);
MountServiceInternal mountServiceInternal = LocalServices.getService(
MountServiceInternal.class);
mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
app.info.packageName);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}


//添加APP和配置文件GID,以便app可以共享某些资源
if (ArrayUtils.isEmpty(permGids)) {
gids = new int[2];
} else {
gids = new int[permGids.length + 2];
System.arraycopy(permGids, 0, gids, 2, permGids.length);
}
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
checkTime(startTime, "startProcess: building args");

......

app.gids = gids;
app.requiredAbi = requiredAbi;
app.instructionSet = instructionSet;

......

// 请求zygote创建进程,成功后会返回新进程的pid,否则会抛出异常
//ProcessStartResult是Process内部类,封装了启动进程的结果
//这是一个阻塞过程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

......

//重置ProcessRecord的成员变量
app.setPid(startResult.pid);
app.usingWrapper = startResult.usingWrapper;
app.removed = false;
app.killed = false;
app.killedByAm = false;
checkTime(startTime, "startProcess: starting to update pids map");

synchronized (mPidsSelfLocked) {
ProcessRecord oldApp;
// 如果已经有一个app占用了这个尚未清理的pid
if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) {
// 清理与此pid相关联的内容
cleanUpApplicationRecordLocked(oldApp, false, false, -1,
true /*replacingPid*/);
}
//将新创建的进程添加到mPidsSelfLocked
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
checkTime(startTime, "startProcess: done updating pids map");
} catch (RuntimeException e) {
// 创建进程失败了,一个常见的情况是由于主动升级导致包被冻结
forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
}
}

这个方法中最重要的就是通过Process.start来创建应用进程;原理是通过socket向Zygote进程发送创建新进程的请求;Zygote进程启动后有一个runSelectLoop循环,当收到客户端请求便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程,创建新进程后将ActivityThread类加载到新进程,并调用ActivityThread.main()方法

3.3.3 Process.start()

源码位于frameworks/base/core/java/android/os/Process.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//开启一个新的进程
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}

3.3.4 Process.startViaZygote()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//通过zygote机制启动新进程
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList<String>();

// 主要工作是生成argsForZygote数组,该数组保存了进程的uid、gid、groups、target-sdk、nice-name等一系列的参数
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
argsForZygote.add("--enable-jni-logging");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
argsForZygote.add("--enable-safemode");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
argsForZygote.add("--enable-debugger");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
argsForZygote.add("--enable-checkjni");
}
if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
argsForZygote.add("--generate-debug-info");
}
if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {
argsForZygote.add("--always-jit");
}
if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {
argsForZygote.add("--native-debuggable");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
argsForZygote.add("--enable-assert");
}
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
argsForZygote.add("--mount-external-read");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
argsForZygote.add("--mount-external-write");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

//TODO optionally enable debuger
//argsForZygote.add("--enable-debugger");

// --setgroups is a comma-separated list
if (gids != null && gids.length > 0) {
StringBuilder sb = new StringBuilder();
sb.append("--setgroups=");

int sz = gids.length;
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(',');
}
sb.append(gids[i]);
}

argsForZygote.add(sb.toString());
}

if (niceName != null) {
argsForZygote.add("--nice-name=" + niceName);
}

if (seInfo != null) {
argsForZygote.add("--seinfo=" + seInfo);
}

if (instructionSet != null) {
argsForZygote.add("--instruction-set=" + instructionSet);
}

if (appDataDir != null) {
argsForZygote.add("--app-data-dir=" + appDataDir);
}

argsForZygote.add(processClass);

if (extraArgs != null) {
for (String arg : extraArgs) {
argsForZygote.add(arg);
}
}

return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}

3.3.5 Process.zygoteSendArgsAndGetResult()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private static ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
// 如果参数格式错误,就尽早抛出异常.
int sz = args.size();
for (int i = 0; i < sz; i++) {
if (args.get(i).indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx("embedded newlines not allowed");
}
}

/**
* 这里就是通过输出流将参数列表写出去
* 获取输入流得到创建进程结果
*/
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;

writer.write(Integer.toString(args.size()));
writer.newLine();

for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}

writer.flush();

// 等待socket返回,这里是否需要设置超时时间,google也在考虑,但是暂时没有加
ProcessStartResult result = new ProcessStartResult();
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();

if (result.pid < 0) {
//创建进程失败,抛出异常
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}

这个方法作用就是通过Socket向zygote进程发送一个参数列表,然后就进入阻塞状态,直到远程Socket服务端返回新创建的进程pid

说到这里我们好像没有见到Socket的影子,只见到了ZygoteState这么一个东西,那它怎么来的呢,可以看见它是上一个方法startViaZygote调用zygoteSendArgsAndGetResult方法传过来的参数,就是这么一句话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
......
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}

3.3.6 Process.openZygoteSocketIfNeeded()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//如果zygote的socket没有打开,那就尝试打开,可能会阻塞或者重连
private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
//向zygote进程发起连接
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}

if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}

//当主zygote没能匹配成功,则采用第二个zygote,发起connect()操作
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
}

if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}

throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}

这个方法会根据当前的abi来选择与zygote还是zygote64进行通信,在init进程解析rc文件的时候,会根据abi型号创建两个zygote;该方法最终会返回一个ZygoteState,它是Process的静态内部类,具体连接实现在ZygoteState.connect方法中

3.3.7 Process.ZygoteState()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* 与zygote进程通信的状态
*
* @hide 仅限内部使用
*/
public static class ZygoteState {
final LocalSocket socket;
final DataInputStream inputStream;
final BufferedWriter writer;
final List<String> abiList;

boolean mClosed;

private ZygoteState(LocalSocket socket, DataInputStream inputStream,
BufferedWriter writer, List<String> abiList) {
this.socket = socket;
this.inputStream = inputStream;
this.writer = writer;
this.abiList = abiList;
}

public static ZygoteState connect(String socketAddress) throws IOException {
DataInputStream zygoteInputStream = null;
BufferedWriter zygoteWriter = null;
final LocalSocket zygoteSocket = new LocalSocket();

try {
zygoteSocket.connect(new LocalSocketAddress(socketAddress,
LocalSocketAddress.Namespace.RESERVED));

zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());

zygoteWriter = new BufferedWriter(new OutputStreamWriter(
zygoteSocket.getOutputStream()), 256);
} catch (IOException ex) {
try {
zygoteSocket.close();
} catch (IOException ignore) {
}

throw ex;
}

String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
Log.i("Zygote", "Process: zygote socket opened, supported ABIS: " + abiListString);

return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
Arrays.asList(abiListString.split(",")));
}

boolean matches(String abi) {
return abiList.contains(abi);
}

public void close() {
try {
socket.close();
} catch (IOException ex) {
Log.e(LOG_TAG,"I/O exception on routine close", ex);
}

mClosed = true;
}

boolean isClosed() {
return mClosed;
}
}

可以看到这里是通过LocalSocket进行进程间通信;这种通信的双方一般是Native层的server端,Framework层的Client端,中间涉及到jni调用。

而Android中的LocalSocket是基于UNIX-domain Socket的,UNIX-domain Socket是在Socket的基础上衍生出来的一种IPC通信机制,因此LocalSocket解决的是同一台主机上不同进程间互相通信的问题。其相对于网络通信使用的socket不需要经过网络协议栈,不需要打包拆包、计算校验,自然的执行效率也高。与大名鼎鼎的binder机制作用一样,都在Android系统中作为IPC通信手段被广泛使用;一般由LocalSocket(Client)和LocalServerSocket(Server)组成通信双方。

那么在本文中AMS所在的system-server进程就充当了Client,zygote进程充当Server,因为zygote进程在创建的时候会在ZygoteInit.main方法中调用ZygoteInit.registerZygoteSocket方法,会实例化一个LocalServerSocket,并且在ZygoteInit.runSelectLoop方法中不停的获取客户端的请求

3.4 Zygote接收到请求

3.4.1 ZygoteInit.main()

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String argv[]) {
try {
registerZygoteSocket(socketName); //为Zygote注册socket
runSelectLoop(abiList); //进入循环模式,获取客户端连接并处理
....
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}

3.4.2 ZygoteInit.runSelectLoop()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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中移除该文件描述符
}
}
}
}
}

这里通过acceptCommandPeer方法获取连接过来的客户端,然后执行ZygoteConnection.runOnce方法处理请求

3.4.3 ZygoteConnection.runOnce()

源码位于 frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* 从socket读取一个启动命令;如果有就fork一个子进程
* 如果fork成功,就会抛出 ZygoteInit.MethodAndArgsCaller异常
*/
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);
}
}

这里先解析客户端发送过来的参数列表,然后调用Zygote.forkAndSpecialize方法

3.4.4 Zygote.forkAndSpecialize()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
/**
* fork一个新的vm实例, 必须使用-Xzygote标志启动当前VM
* 新实例保留所有root功能
*/
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
String instructionSet, String appDataDir) {
VM_HOOKS.preFork();
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
instructionSet, appDataDir);

VM_HOOKS.postForkCommon();
return pid;
}

这里在fork新进程的时候会先调用 VM_HOOKS.preFork()

3.4.5 ZygoteHooks.preFork()

1
2
3
4
5
public void preFork() {
Daemons.stop(); //停止4个Daemon子线程
waitUntilAllThreadsStopped(); //等待所有子线程结束
token = nativePreFork(); //完成gc堆的初始化工作
}

这个方法的主要目的是停止zygote进程的四个daemon子线程,分别是ReferenceQueueDaemon,FinalizerDaemon,FinalizerWatchdogDaemon,HeapTaskDaemon;直到zygote是是单线程,以便于提高fork效率;

fork新进程是调用native方法,经过jni调用

3.4.6 com_android_internal_os_Zygote.nativeForkAndSpecialize()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint debug_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
// 将CAP_WAKE_ALARM赋予蓝牙进程
jlong capabilities = 0;
if (uid == AID_BLUETOOTH) {
capabilities |= (1LL << CAP_WAKE_ALARM);
}

return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
rlimits, capabilities, capabilities, mount_external, se_info,
se_name, false, fdsToClose, instructionSet, appDataDir);
}

3.4.7 com_android_internal_os_Zygote.ForkAndSpecializeCommone()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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) {
//设置子进程的signal信号处理函数
SetSigChldHandler();
//fork子进程
pid_t pid = 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); //设置线程名为,方便调试
}
//在Zygote子进程中,设置信号SIGCHLD的处理器恢复为默认行为
UnsetSigChldHandler();
//等价于调用zygote.callPostForkChildHooks()
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
is_system_server ? NULL : instructionSet);
...

} else if (pid > 0) {
//进入父进程,即Zygote进程
}
return pid;
}

这里会通过fork()方法创建进程

3.4.8 fork.fork()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int fork() {
__bionic_atfork_run_prepare(); // fork完成前,父进程回调方法

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进程结束后会在ForkAndSpecializeCommon函数中调用CallStaticVoidMethod。这就是反射调用zygote.callPostForkChildHooks()

3.4.9 zygote.callPostForkChildHooks()

1
2
3
4
private static void callPostForkChildHooks(int debugFlags, boolean isSystemServer,
String instructionSet) {
VM_HOOKS.postForkChild(debugFlags, isSystemServer, instructionSet);
}

3.4.10 ZygoteHooks.postForkChild()

源码位于libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

1
2
3
4
5
public void postForkChild(int debugFlags, String instructionSet) {
nativePostForkChild(token, debugFlags, instructionSet);
//将当前时间设置为新进程随机数种子
Math.setRandomSeedInternal(System.currentTimeMillis());
}

nativePostForkChild又通过jni调用dalvik_system_ZygoteHooks.ZygoteHooks_nativePostForkChild方法

3.4.11 dalvik_system_ZygoteHooks.ZygoteHooks_nativePostForkChild()

源码位于art/runtime/native/dalvik_system_ZygoteHooks.cc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
static void ZygoteHooks_nativePostForkChild(JNIEnv* env,
jclass,
jlong token,
jint debug_flags,
jboolean is_system_server,
jstring instruction_set) {


//此处token是由nativePreFork()创建的,记录着当前线程
Thread* thread = reinterpret_cast<Thread*>(token);
// Our system thread ID, etc, has changed so reset Thread state.
//设置新进程的主线程id
thread->InitAfterFork();
EnableDebugFeatures(debug_flags);

// Update tracing.
if (Trace::GetMethodTracingMode() != TracingMode::kTracingInactive) {
Trace::TraceOutputMode output_mode = Trace::GetOutputMode();
Trace::TraceMode trace_mode = Trace::GetMode();
size_t buffer_size = Trace::GetBufferSize();

// Just drop it.
Trace::Abort();

// Only restart if it was streaming mode.
// TODO: Expose buffer size, so we can also do file mode.
if (output_mode == Trace::TraceOutputMode::kStreaming) {
const char* proc_name_cutils = get_process_name();
std::string proc_name;
if (proc_name_cutils != nullptr) {
proc_name = proc_name_cutils;
}
if (proc_name_cutils == nullptr || proc_name == "zygote" || proc_name == "zygote64") {
// Either no process name, or the name hasn't been changed, yet. Just use pid.
pid_t pid = getpid();
proc_name = StringPrintf("%u", static_cast<uint32_t>(pid));
}

std::string trace_file = StringPrintf("/data/misc/trace/%s.trace.bin", proc_name.c_str());
Trace::Start(trace_file.c_str(),
-1,
buffer_size,
0, // TODO: Expose flags.
output_mode,
trace_mode,
0); // TODO: Expose interval.
if (thread->IsExceptionPending()) {
ScopedObjectAccess soa(env);
thread->ClearException();
}
}
}

if (instruction_set != nullptr && !is_system_server) {
ScopedUtfChars isa_string(env, instruction_set);
InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());
Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload;
if (isa != kNone && isa != kRuntimeISA) {
action = Runtime::NativeBridgeAction::kInitialize;
}
Runtime::Current()->InitNonZygoteOrPostFork(
env, is_system_server, action, isa_string.c_str());
} else {
Runtime::Current()->InitNonZygoteOrPostFork(
env, is_system_server, Runtime::NativeBridgeAction::kUnload, nullptr);
}
}

3.4.12 Runtime::InitNonZygoteOrPostFork()

源码位于art/runtime/runtime.cc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void Runtime::InitNonZygoteOrPostFork(
JNIEnv* env, bool is_system_server, NativeBridgeAction action, const char* isa) {
is_zygote_ = false;

if (is_native_bridge_loaded_) {
switch (action) {
case NativeBridgeAction::kUnload:
//卸载用于跨平台的桥连库
UnloadNativeBridge();
is_native_bridge_loaded_ = false;
break;

case NativeBridgeAction::kInitialize:
InitializeNativeBridge(env, isa);
break;
}
}

// Create the thread pools.
//创建Java堆处理的线程池
heap_->CreateThreadPool();
// Reset the gc performance data at zygote fork so that the GCs
// before fork aren't attributed to an app.
//重置gc性能数据,以保证进程在创建之前的GCs不会计算到当前app上。
heap_->ResetGcPerformanceInfo();


if (!is_system_server &&
!safe_mode_ &&
(jit_options_->UseJitCompilation() || jit_options_->GetSaveProfilingInfo()) &&
jit_.get() == nullptr) {
// Note that when running ART standalone (not zygote, nor zygote fork),
// the jit may have already been created.
//当flag被设置,并且还没有创建JIT时,则创建JIT
CreateJit();
}
//设置信号处理函数
StartSignalCatcher();

// Start the JDWP thread. If the command-line debugger flags specified "suspend=y",
// this will pause the runtime, so we probably want this to come last.
//启动JDWP线程,当命令debuger的flags指定"suspend=y"时,则暂停runtime
Dbg::StartJdwp();
}

fork完成后继续Zygote.forkAndSpecialize方法第三步

3.4.12 ZygoteHooks.postForkCommon()

1
2
3
4
5
6
7
8
9
10
public void postForkCommon() {
Daemons.start();
}

public static void start() {
ReferenceQueueDaemon.INSTANCE.start();
FinalizerDaemon.INSTANCE.start();
FinalizerWatchdogDaemon.INSTANCE.start();
HeapTaskDaemon.INSTANCE.start();
}

主要作用是在fork新进程后将之前停掉的四个Daemon线程启动起来

forkAndSpecialize 总结

  • preFork:停止4个Daemon子线程,初始化GC
  • nativeForkAndSpecialize:调用Linux的fork()子进程,设置新进程的主线程id,重置gc性能数据,设置信号处理函数等功能
  • postForkCommon:重新启动四个daemon子线程
  • forkAndSpecialize执行结束,即创建新进程后,会有两次返回,第一次回到ZygoteConnection.runOnce方法,执行子进程handleChildProc方法;第二次回到该方法,执行zygote进程的handleParentProc方法

3.4.13 回调子进程ZygoteConnection.handleChildProc()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* 处理子进程的post-fork设置,并根据需要关闭套接字,根据需要重新打开stdio,
* 如果成功则最终抛出MethodAndArgsCaller,如果失败则返回。
*/
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
/**
* 当执行到达这里时,native code关闭了两个实际的Zygote socket连接,
* 并在它们的位置替换了/ dev / null。 LocalSocket对象仍需要正确关闭。
*/

closeSocket();
ZygoteInit.closeServerSocket();

if (descriptors != null) {
try {
Os.dup2(descriptors[0], STDIN_FILENO);
Os.dup2(descriptors[1], STDOUT_FILENO);
Os.dup2(descriptors[2], STDERR_FILENO);

for (FileDescriptor fd: descriptors) {
IoUtils.closeQuietly(fd);
}
newStderr = System.err;
} catch (ErrnoException ex) {
Log.e(TAG, "Error reopening stdio", ex);
}
}

//设置进程名
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}


if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
} else {
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}

3.4.14 RuntimeInit.zygoteInit()

1
2
3
4
5
6
7
8
9
10
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); // 应用初始化
}

3.4.15 RuntimeInit.commonInit()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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();
}

3.4.16 RuntimeInit.nativeZygoteInit()

nativeZygoteInit()所对应的jni方法如下,源码位于frameworks/base/core/jni/AndroidRuntime.cpp

1
2
3
4
5
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
//此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
gCurRuntime->onZygoteInit();
}

3.4.17 app_main.onZygoteInit()

源码位于 frameworks/base/cmds/app_process/app_main.cpp

1
2
3
4
5
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool(); //启动新binder线程
}

ProcessState::self():主要工作是调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于交互操作。startThreadPool()是创建一个新的binder线程,不断进行talkWithDriver(),与Binder驱动交流

继续执行zygoteInit方法中的最后一个方法

3.4.18 RuntimeInit.applicationInit()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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为”android.app.ActivityThread”
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

3.4.19 RuntimeInit.invokeStaticMain()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
}

重点看最后一个方法,通过反射获取ActivityThread类的main方法参数,然后抛出MethodAndArgsCaller异常,其中构造方法中m是指main方法,argv是AMS发送过来的参数列表;但是抛出异常后怎么弄呢,我们知道一个方法抛异常,会一直往上走到调用方法,直到一个方法捕获了异常。在这里就会一直抛到ZygoteInit.main方法才捕获了异常,然后去执行MethodAndArgsCaller.run方法

3.4.20 MethodAndArgsCaller.run()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 {
//反射调用,由上面可知这里会调用到ActivityThread.main()方法
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);
}
}
}

走到这里就要进入ActivityThread了,它管理着应用程序进程中主线程的执行,在ActivityManager请求时调度和执行Activity,Service,Broadcast和其它操作

3.4.21 ActivityThread.main()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {

......
//创建主线程的Looper
Looper.prepareMainLooper();
//关联AMS
ActivityThread thread = new ActivityThread();
thread.attach(false);

//初始化主线程Handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}

// 进行主线程消息循环
Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");
}

主要工作:设置进程名,打开binder驱动,启动新的binder线程;然后设置art虚拟机参数,再反射调用目标类的main()方法,即ActivityThread.main()方法

至此,进程创建完毕,并且也有了主线程,剩下的便是启动Activity和关联context等初始化操作了

3.4.22 回调zygote进程ZygoteConnection.handleParentProc()

子进程fork方法执行完成回调第一次给子进程后,还会回调一次给zygote进程

具体是在ZygoteConnection.runOnce中调用handleParentProc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private boolean handleParentProc(int pid,
FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {

if (pid > 0) {
setChildPgid(pid);
}
....
try {

mSocketOutStream.writeInt(pid);
mSocketOutStream.writeBoolean(usingWrapper);
} catch (IOException ex) {
Log.e(TAG, "Error writing to command socket", ex);
return true;
}

return false;
}

这个方法主要是为了通知system server进程,新进程已经创建完成

注意
  • APP或者桌面启动,需要使用Binder机制告诉AMS(因为启动方有自己的进程,AMS在system server进程),AMS请求zygote进程是通过Socket
  • Process.start方法是阻塞的,只有等进程创建完成才会返回
  • zygote进程fork进程一次,会有两次返回,在zygote进程和子进程分别返回一次,这样子线程就能执行ZygoteConnection.handleChildProc及以后的逻辑;zygote进程通过ZygoteConnection.handleParentProc通知system server进程新进程已经创建完成
fork解释

可能你会疑虑,明明是在zygote进程中的ZygoteConnection.runOnce方法中去执行fork操作,那么fork结束后返回不应该还是在zygote进程中吗?

这里需要了解下fork的逻辑:

fork()采用copy on write技术,这是linux创建进程的标准方法,调用一次,返回两次。当父子进程任一方修改内存数据时(这是on-write时机),才发生缺页中断,从而分配新的物理内存(这是copy操作)。
copy-on-write原理:写时拷贝是指子进程与父进程的页表都所指向同一个块物理内存,fork过程只拷贝父进程的页表,并标记这些页表是只读的。父子进程共用同一份物理内存,如果父子进程任一方想要修改这块物理内存,那么会触发缺页异常(page fault),Linux收到该中断便会创建新的物理内存,并将两个物理内存标记设置为可写状态,从而父子进程都有各自独立的物理内存。

其实就是fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的)

可以这样想象,子进程就是把zygote进程复制了一遍,两个进程都阻塞在这里;但在fork之后,他们就开始分别作不同的工作,正如fork原意【分支】一样,在zygote进程的ZygoteConnection.runOnce方法中,fork返回子进程id,然后执行ZygoteConnection.handleParentProc;但是在子进程的ZygoteConnection.runOnce方法中,fork返回是0,就会去执行ZygoteConnection.handleChildProc;这样父子进程从此分家

4. ActivityThrad的工作逻辑

4.1 前言

我们知道在Sun的Java体系中和C语言中的类或者程序入口点都是main方法,那我们的Android程序入口是不是也是某个类的main方法呢?

有一点很奇怪的是,我们平时开发中好像没接触过main方法,基本上都是与四大组件(还有一个Fragment)和Application打交道;要想弄清楚这是怎么回事,就必须要了解下当你点击手机桌面上某个APP的icon后,它是怎么从无到有运行在你的眼前的呢?

当一个应用进程被创建之后,会把ActivityThread这个类加载到新的进程中来,接下来这个应用的一切操作(比如Activity的创建启动)就从ActivityThread这个类开始展开

4.2 类简称

  • ActivityManagerService:AMS
  • ActivityManagerNative:AMN
  • ActivityManagerProxy:AMP
  • ActivityThread :AT
  • ApplicationThread:APT
  • ApplicationThreadNative:ATN
  • ApplicationThreadProxy:ATP
  • ActivityStackSupervisor:ASS

4.3 类简介

这个章节的分析将会接触到大量跨进程通信,需要用到AIDL,其中涉及到的类及Activity启动相关类如下,AIDL的实现模式都是固定的

4.3.1

  • IActivityManager:作为应用进程请求系统进程的接口,这时候应用进程是客户端进程,系统进程是服务端进程,客户端和服务端进程都实现且遵循这个接口规则
  • ActivityManagerNative:作为服务端的“桩(Stub)”,其主要职责就是对远程(客户端进程)传递过来的数据进行”反序列化(unparcel)”
  • ActivityManagerProxy:作为服务的“代理(Proxy)”,运行在客户端进程,其主要职责就是将数据进行“序列化(parcel)”,再传递给远程的“桩(Stub)”
  • ActivityManagerService:IActivityManager接口中定义的业务的具体实现,运行在服务端,对“桩(Stub)”做了继承扩展

4.3.2

  • IApplicationThread: 作为系统进程请求应用进程的接口,这时候应用进程是服务端进程,系统进程是客户端进程,客户端和服务端进程都实现且遵循这个接口规则
  • ApplicationThreadNative:同理于ActivityManagerNative
  • ApplicationThreadProxy:同理于ActivityManagerProxy
  • ApplicationThread:同理于ActivityManagerService,负责响应系统进程发起的请求,帮助AMS管理相关Application中的Activity的生命周期,是ActivityThread内部类(ActivityThread是应用进程的主线程),接收到系统进程请求后通过Handler往主线程发消息,这样ApplicationThread就轻松将具体执行任务的工作转交给了主线程,用来实现AMS和AT之间的交互

4.3.3

  • ProcessRecord:保存了进程运行时的信息,AMS通过ProcessRecord来维护进程运行时的状态信息,需要将应用进程绑定到ProcessRecord才能开始一个Application的构建(每个应用进程在AMS对应一个ProcessRecord)
  • ActivityRecord:保存Activity运行时的信息,AMS通过ActivityRecord来维护Activity运行时的状态信息,需要将Activity绑定到AMS中的ActivityRecord才能开始Activity的生命周期(每个Activity在AMS对应一个ActivityRecord,其实就是服务器端的Activity对象的映像)
  • TaskRecord:AMS抽象出来的一个Task的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序,如果了解过Activity的启动模式就知道这个用处了
  • ActivityStack:AMS对Activity设计的一种堆栈机制用于管理Activity,为了让这许多Activity协同工作而不至于产生混乱,其遵循先进后出的原则,系统总是显示位于栈顶的Activity

4.3.4

  • ActivityThread:APP的入口类,从main方法开始执行,就是大家口中的UI线程或者主线程,与AMS一起完成四大组件的工作
  • Instrumentation:每一个应用程序只有一个Instrumentation实例,在BindApplication创建的,每个Activity内部拥有一个该对象的引用,ActivityThread对组件的操作最后都是交给它去做具体的执行

4.3.5

  • ApplicationInfo:保存了应用程序的信息,包括AndroidManifest.xml中检索的信息
  • Context:Activity的上下文
  • ContextWrapper:继承Context,为了使用方便,对Context进行包装,而无需修改Context,内部包含一个真正的Context引用,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象,即ContextImpl对象
  • Application:继承ContextWrapper,ActivityThread的上下文,用户可以继承它自定义自己的Application类,用于维护全局应用程序状态的基类
  • ContextImpl:继承Context,真正实现了Context中所有函数,应用程序中调用的各种Context类的方法,其实现均来自于该类;它为Activity和其他应用程序组件提供基本上下文对象

4.3.6 代理和桩的理解

“代理(Proxy)”和“桩(Stub)”是Binder接口实现时成对出现的概念。可以对应到一个生活中的例子:银行的取款机就像是银行的业务代理(Proxy),客户只需要通过取款机,就能方便地完成存、取款等业务。对于客户来说,不用关心银行是什么样,钱到哪去了,只要通过代理能完成自己的业务就行了;对于取款机这个代理而言,它需要连接银行的服务器(Stub),完成数据传递,将客户的操作反馈到中心

4.4 ActivityThread入口

源码位于frameworks/base/core/java/android/app/ActivityThread.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public static void main(String[] args) {

......

//实例化了UserEnvironment,便于访问存储路径
//像平时使用的Environment.getExternalStorageDirectory出自UserEnvironment类
Environment.initForCurrentUser();

// 设置路径 确保用户能正确访问CA证书
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);

//设置进程名,Process类是进程管理器
Process.setArgV0("<pre-initialized>");

//创建主线程的Looper
Looper.prepareMainLooper();

//创建ActivityThread 对象,并关联到AMS
ActivityThread thread = new ActivityThread();
thread.attach(false);

//对主线程Handler赋值
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}

// 开启主线程循环器,不断的读取消息 派发处理消息
Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");
}

这个方法三处比较重要

  • 创建主线程的Looper,并调用Loop方法,这样主线程就有了自己的消息队列并不停的从中取消息,然后处理

  • 创建ActivityThread 对象,这个过程中会实例化几个重要的成员变量

    • ApplicationThread mAppThread = new ApplicationThread()
    • Looper mLooper = Looper.myLooper() 获取主线程的Looper
    • H mH = new H() H继承Handler,用来处理组件的生命周期
  • 调用attach方法,这个方法很重要,看下方

4.4.1 AT.attach()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;//mSystemThread表明是system app 还是普通app
if (!system) { //main方法传入的是false
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
//开启JIT
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
//设置标识此应用程序/进程的对象,以报告VM错误。
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//创建ActivityManagerProxy对象
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//通过Binder跨进程调用AMS中的attachApplication
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//观察是否到heap内存上限
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
//当已使用内存超过虚拟机总内存的3/4,就请求释放内存
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
});
} else {
// 不要在这里设置application,如果系统崩溃,我们没办法显示警告信息
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}

//添加dropbox日志到libcore
DropBox.setReporter(new DropBoxReporter());
//添加Config回调接口
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
mResourcesManager.getConfiguration().getLocales());

// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;

sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
  • 该方法的参数表明是否是system app调用,然后赋值mSystemThread;显然这里是普通app,进入第一个分支
  • 接下来调用ensureJitEnabled()方法,目的是开启虚拟机即时编译功能,Jit全称Just-In-Time,JIT 是一种在运行时同步将字节码转化成机器码的编译器,Dalvik 直接运行转化后的机器码
  • 通过ActivityManagerNative.getDefault()获取AMS的Binder代理对象,然后将APT对象发送给AMS,因为APT继承ATN,这样间接继承了IBinder接口,具备跨进程传输能力
  • 通过BinderInternal类去观察虚拟机内存使用情况
  • 添加dropbox日志到libcore
  • 添加Config回调接口
  • 接下来从ActivityManagerNative.getDefault()开始分析

4.4.2 AMN.getDefault()

源码位于frameworks/base/core/java/android/app/ActivityManagerNative.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* 获取系统中全局的ActivityManager,这是与远程AMS通信的接口
*/
static public IActivityManager getDefault() {
return gDefault.get();
}

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
//将Binder对象转换成activity manager接口,并在需要时生成代理对象
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
//如果是同一个进程,那就直接返回ActivityManagerNative自己
return in;
}
//如果跨进程,那就将这个IBinder构建成代理对象返回
return new ActivityManagerProxy(obj);
}

当前应用所在进程与AMS所在的system server进程不是一个进程,如果想要与AMS通信,就必须要使用Binder机制,这里跨进程通信的过程就是一个典型的AIDL实现

这里是把ActivityThread当做Client,AMS当做Server,这里是跨进程,就需要获取AMS在Client的Binder代理对象,即构建AMP返回,所以这里的IActivityManager实质上是AMP对象,接下来进入AMP

4.4.3 AMP.attachApplication()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void attachApplication(IApplicationThread app) throws RemoteException
{
//从Parcel池中获取Parcel对象(通讯载体),装载传递给AMS的数据
Parcel data = Parcel.obtain();
//同上,不过是装载AMS返回的数据
Parcel reply = Parcel.obtain();
//Binder唯一标志
data.writeInterfaceToken(IActivityManager.descriptor);
//asBinder()方法是返回与IApplicationThread 接口相关联的Binder对象(Binder对象实际类型是ATN)
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}

因为是Binder代理对象,所以这里的mRemote是BinderProxy类型,进入看看

4.4.4 BinderProxy.transact()

源码位于 frameworks/base/core/java/android/os/Binder.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
*
* @param code 每个AIDL函数都有一个编号,在跨进程的时候,不会传递函数,而是传递编号告诉Server调用哪个函数
* @param data Client要发送的数据
* @param reply Server返回的数据
* @param flags
* @return
* @throws RemoteException
*/
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
return transactNative(code, data, reply, flags);
}
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException

这里最终调用到了native层,接下来经过一系列函数调用,最终调用到了**talkWithDriver()*跟驱动交互,这个函数最后通过ioctl系统调用,Client进程陷入内核态,Client调用attachApplication方法的线程挂起等待返回;驱动完成一系列的操作之后唤醒AMS所在进程,调用了AMS所在进程本地对象的onTransact函数(实际上由Server端线程池完成),这里就调用了AMN的onTransact方法(AMN即Binder本地对象)

4.4.5 AMN.onTransact()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
//再将binder对象转换成接口(实际类型是ATP)
IApplicationThread app = ApplicationThreadNative.asInterface(
data.readStrongBinder());
if (app != null) {
attachApplication(app);
}
reply.writeNoException();
return true;
}
}

return super.onTransact(code, data, reply, flags);
}

在AMS所在进程里面,onTransact根据编号调用相关函数;在这个例子里面,由AMS的Binder本地对象(AMN)调用了Server端的attachApplication方法,从这里开始就正式进入AMS了

这边很重要的一点是:
虽然在APP进程中是将APT作为参数发送给AMS所在进程,但是因为是跨进程,经过Binder驱动处理后,AMS接收到的是APT的代理对象,即ATP,然后作为参数传给了AMS.attachApplication

4.4.6 AMS.attachApplication()

1
2
3
4
5
6
7
8
9
10
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
//获取正在attach的应用进程id
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}

这里的thread就是ATP了,AMS就用这个跟APP进程的APT通信
注意:这时候AMS所在进程作为Client,APP进程作为Server,记住一点,谁主动发起调用,谁就是Client端,你会发现这又是一个AIDL典型的实现

4.4.7 AMS.attachApplicationLocked()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
		
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {

// 通过pid查找正在attach的application record
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}

if (app == null) {
//找不到对应的ProcessRecord,就杀掉pid对应的进程
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid);
//TODO: killProcessGroup(app.info.uid, pid);
} else {
try {
//退出这个应用进程的Looper
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
return false;
}

// 第一次attach,app.thread应该为null
//如果不为null,说明attach在之前的进程,那就清除它
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}

// 述说整个进程

final String processName = app.processName;
try {
//注册该进程的死亡回调
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}

EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);

//设置应用进程信息

//这一步结束,app.thread就不会为null
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;

// 使用此标志来决定当用户在稍后解锁时是否需要安装provider
app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
//移出进程启动超时消息
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;

//如果应用程序中存在正在启动的providers,那就延迟10s发送Contentprovider超时消息
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}

try {

//获取ApplicationInfo。它保存了从AndroidManifest.xml中检索出的application标签下的信息
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
if (profileFd != null) {
profileFd = profileFd.dup();
}
//用于传递profiler设置的系统私有api
ProfilerInfo profilerInfo = profileFile == null ? null
: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
//绑定应用
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
//更新进程lru列表
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// 如果bind失败,那就重启app进程,有可能会无限循环
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
startProcessLocked(app, "bind fail", processName);
return false;
}

// 从待启动应用列表清除这个ProcessRecord
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);

boolean badApp = false;
boolean didSomething = false;

// 检测最顶层的可见activity是否正在等待运行在这个进程(启动activity)
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;//didSomething表示是否有启动四大组件
}
} catch (Exception e) {
badApp = true;
}
}

// 查找所有要运行在这个进程中的sevice
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}

// 检测这个进程是否有下一个Broadcast receiver
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
// 如果app因为尝试启动Broadcast receiver而死亡,就设置badApp = true
badApp = true;
}
}

//检查下一个backup代理是否在此过程中
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
notifyPackageUse(mBackupTarget.appInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
try {
thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
mBackupTarget.backupMode);
} catch (Exception e) {
badApp = true;
}
}

//如果以上组件启动出错,则需要杀死进程并移除记录
if (badApp) {
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}

//如果没有启动任何组件,那么didSomething为false
//调整进程的oom_adj值, oom_adj相当于一种优先级
//当内存出现不足时,该进程是最先被系统“杀死”
if (!didSomething) {
updateOomAdjLocked();
}

return true;
}

小结

  1. 通过pid查找当前进程对应的ProcessRecord
  2. 如果ProcessRecord == null,说明正在attach的进程不存在,如果pid有效就杀掉pid对应的进程;反之让刚创建的activitythread退出looper循环;最后直接return
  3. 如果查找出来的ProcessRecord 中保存的IApplicationThread不为空,说明它是上个进程的,那就需要清除它
  4. 注册该进程的死亡回调,当进程死亡时会通过binder回调,来通知system_server进程死亡的消息
  5. 重新设置ProcessRecord信息
  6. 调用thread.bindApplication绑定Application到ActivityThread
  7. 处理activity,service,Broadcast receiver
  8. kill掉bad应用

我们先看第二步,退出looper循环

thread.scheduleExit()

这里的thread是入参IApplicationThread,由上面分析可知,传过来的是APT在客户端的代理ATP,那就走到ATP.scheduleExit

4.4.8 ATP.scheduleExit()

1
2
3
4
5
6
7
public final void scheduleExit() throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}

因为是代理对象,所以这里的mRemote是BinderProxy类型,调用后经过底层Binder调用会走到服务端的ATN.onTransact
(跟上面的AT调用AMS是一样的流程)

4.4.9 ATN.onTransact()

1
2
3
4
5
6
7
8
9
10
11
12
13
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case SCHEDULE_EXIT_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
scheduleExit();
return true;
}
}

return super.onTransact(code, data, reply, flags);
}

scheduleExit()具体实现在APT

4.4.10 APT.scheduleExit()

1
2
3
public final void scheduleExit() {
sendMessage(H.EXIT_APPLICATION, null);
}

继续调用到AT

4.4.11 AT.sendMessage()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
	private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
private class H extends Handler {

public void handleMessage(Message msg) {

switch (msg.what) {
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;

}
}

}

最终会将主线程的消息队列清空并退出looper;这一系列调用就是一个AIDL的实现

再看第四步,注册APP进程的死亡通知

thread.asBinder().linkToDeath

上面说了thread是代理对象,调用的是ATP.asBinder(),通过adBinder获取到的Binder类型是BinderProxy

4.4.12 BinderProxy.linkToDeath()

1
2
public native void linkToDeath(DeathRecipient recipient, int flags)
throws RemoteException;

这是一个native方法,经过jni调用后

4.4.13 android_util_Binder.linkToDeath()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
static const JNINativeMethod gBinderProxyMethods[] = {
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}
};

static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
jobject recipient, jint flags) // throws RemoteException
{
if (recipient == NULL) {
//jni抛异常
jniThrowNullPointerException(env, NULL);
return;
}

//获取BpBinder
BinderProxyNativeData *nd = getBPNativeData(env, obj);
IBinder* target = nd->mObject.get();

LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);

if (!target->localBinder()) {
DeathRecipientList* list = nd->mOrgue.get();
sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
//在这里建立死亡回调
status_t err = target->linkToDeath(jdr, NULL, flags);
if (err != NO_ERROR) {
// 添加到death recipient失败, 那清除引用
jdr->clearReference();
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
}
}
}
status_t BpBinder::linkToDeath(
const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
{
Obituary ob;
ob.recipient = recipient; //该对象为JavaDeathRecipient
ob.cookie = cookie; // cookie=NULL
ob.flags = flags; // flags=0
{
AutoMutex _l(mLock);
if (!mObitsSent) { //没有执行过sendObituary,则进入该方法
if (!mObituaries) {
mObituaries = new Vector<Obituary>;
if (!mObituaries) {
return NO_MEMORY;
}
getWeakRefs()->incWeak(this);
IPCThreadState* self = IPCThreadState::self();
//向Binder驱动写命令
self->requestDeathNotification(mHandle, this);
//给驱动发消息
self->flushCommands();
}
//将新创建的Obituary添加到mObituaries
ssize_t res = mObituaries->add(ob);
return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
}
}
return DEAD_OBJECT;
}

status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
{
mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
mOut.writeInt32((int32_t)handle);
mOut.writePointer((uintptr_t)proxy);
return NO_ERROR;
}
void IPCThreadState::flushCommands()
{
if (mProcess->mDriverFD <= 0)
return;
talkWithDriver(false);
}

这里最终会调用talkWithDriver告诉Binder驱动

4.4.14 IPCThreadState::talkWithDriver()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}

binder_write_read bwr;
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();

// This is what we'll read.
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}

bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {

//将命令发送给Binder驱动
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;

err = INVALID_OPERATION;

if (mProcess->mDriverFD <= 0) {
err = -EBADF;
}
} while (err == -EINTR);

......
return err;
}

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
...

binder_lock(__func__);
thread = binder_get_thread(proc); //获取binder_thread
switch (cmd) {
case BINDER_WRITE_READ: //进行binder的读写操作
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
if (ret)
goto err;
break;
case ...
}
ret = 0;

err:
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
binder_unlock(__func__);
...
return ret;
}

static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread)
{
int ret = 0;
struct binder_proc *proc = filp->private_data;
void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;

if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { //把用户空间数据ubuf拷贝到bwr
ret = -EFAULT;
goto out;
}

if (bwr.write_size > 0) { //此时写缓存有数据
ret = binder_thread_write(proc, thread,
bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
...
}

if (bwr.read_size > 0) { //此时读缓存无数据
...
}

if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { //将内核数据bwr拷贝到用户空间ubuf
ret = -EFAULT;
goto out;
}
out:
return ret;
}

//处理进程发送给Binder驱动的请求
static int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed) {
uint32_t cmd;
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
void __user *ptr = buffer + *consumed;
void __user *end = buffer + size;

while (ptr < end && thread->return_error == BR_OK) {
get_user(cmd, (uint32_t __user *)ptr); //获取命令
switch (cmd) {
case BC_REQUEST_DEATH_NOTIFICATION:
//添加到当前线程的todo队列
list_add_tail(&ref->death->work.entry, &thread->todo);
break;
case ...;
}
}
}

最后一步表明只要对端进程挂掉,Binder是在底层可以从todo链表中拿出来client的信息,然后调用对应的回调方法

接下来看第六步,绑定应用

thread.bindApplication

调用原理跟上面一样,这里就不在继续阐述了,最终会调用到APT.bindApplication

4.4.15 APT.bindApplication()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {

if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}

setCoreSettings(coreSettings);

AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}

public void setCoreSettings(Bundle coreSettings) {
sendMessage(H.SET_CORE_SETTINGS, coreSettings);
}

这里通过handler向主线程(AT)发送了两条消息SET_CORE_SETTINGS,BIND_APPLICATION

4.4.16 AT.H.SET_CORE_SETTINGS、AT.H.BIND_APPLICATION

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private class H extends Handler {

public void handleMessage(Message msg) {

switch (msg.what) {
case SET_CORE_SETTINGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
handleSetCoreSettings((Bundle) msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}

}

4.4.17 AT.handleSetCoreSettings()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void handleSetCoreSettings(Bundle coreSettings) {
synchronized (mResourcesManager) {
mCoreSettings = coreSettings;
}
onCoreSettingsChange();
}

private void onCoreSettingsChange() {
boolean debugViewAttributes =
mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
if (debugViewAttributes != View.mDebugViewAttributes) {
View.mDebugViewAttributes = debugViewAttributes;

// 要求所有activity重启以进行更改
for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
false /* preserveWindow */);
}
}
}

4.4.18 AT.handleBindApplication()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
private void handleBindApplication(AppBindData data) {

// 将UI线程作为sensitive thread 注册到虚拟机.
VMRuntime.registerSensitiveThread();
if (data.trackAllocation) {
DdmVmInternal.enableRecentAllocations(true);
}

// 设置进程启动时间
Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());

mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);

mProfiler = new Profiler();
if (data.initProfilerInfo != null) {
mProfiler.profileFile = data.initProfilerInfo.profileFile;
mProfiler.profileFd = data.initProfilerInfo.profileFd;
mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
}

// 设置进程名, 也就是说进程名是在进程真正创建以后的BIND_APPLICATION过程中才取名
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
UserHandle.myUserId());

if (data.persistent) {
// Persistent processes on 在低内存设备上无法使用硬件加速绘图,禁用以节省内存
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(false);
}
}

if (mProfiler.profileFd != null) {
mProfiler.startProfiling();
}

// 如果sdk版本在Android3.1.x(API12)或更早版本,需要设置Asynctask中使用的线程池,这样任务是并行执行,在高版本是串行执行
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

//如果版本大于LOLLIPOP,就不支持回收正在使用的Message
Message.updateCheckRecycle(data.appInfo.targetSdkVersion);

/*
* 重置时区
*/
TimeZone.setDefault(null);
LocaleList.setDefault(data.config.getLocales());

synchronized (mResourcesManager) {
/*
* 更新系统配置
*/
mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
applyCompatConfiguration(mCurDefaultDisplayDpi);
}

//获取LoadedApk对象
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);

//api11以后禁止在主线程使用网络
if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
StrictMode.enableDeathOnNetwork();
}

//api24及以后禁止使用file://这种格式的Uri;引入Fileprovide
if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
StrictMode.enableDeathOnFileUriExposure();
}
......

/**
* 因为前面重置了时区,所以这里需要初始化http代理.
* 这里也是AIDL的运用
*/
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try {
final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
Proxy.setHttpProxySystemProperty(proxyInfo);
} catch (RemoteException e) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw e.rethrowFromSystemServer();
}
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

// Instrumentation会影响类加载器,所以在设置app的context之前初始化.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
try {
ii = new ApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find instrumentation info for: " + data.instrumentationName);
}

mInstrumentationPackageName = ii.packageName;
mInstrumentationAppDir = ii.sourceDir;
mInstrumentationSplitAppDirs = ii.splitSourceDirs;
mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
mInstrumentedAppDir = data.info.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir();
} else {
ii = null;
}

//创建ContextImpl上下文
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales());

if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
final File cacheDir = appContext.getCacheDir();
if (cacheDir != null) {
// 设置临时文件缓存目录
System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
}
// 设置 generated/compiled graphics code 的缓存位置.
final Context deviceContext = appContext.createDeviceProtectedStorageContext();
final File codeCacheDir = deviceContext.getCodeCacheDir();
if (codeCacheDir != null) {
setupGraphicsSupport(data.info, codeCacheDir);
}
}

// 安装 Network Security Config Provider. 必须在应用程序代码加载前安装
NetworkSecurityConfigProvider.install(appContext);

// 继续实例化instrumentation.
if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}

final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

if (mProfiler.profileFile != null && !ii.handleProfiling
&& mProfiler.profileFd == null) {
mProfiler.handlingProfiling = true;
final File file = new File(mProfiler.profileFile);
file.getParentFile().mkdirs();
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
} else {
//第一次进来肯定是null,在这里实例化,所有activity的生命周期方法回调前都会调用该对象相关方法
mInstrumentation = new Instrumentation();
}

if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
//清除内存增长上限
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
} else {
// Small heap, clamp to the current growth limit and let the heap release
// pages after the growth limit to the non growth limit capacity. b/18387825
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
}

// 应用程序和provider在设置期间允许磁盘访问,这有可能会阻塞ordered broadcasts的处理
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
try {
// 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;

// 不要在 restricted 模式中提供provider; 他们可能依赖于APP自定义的类
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
// 对于包含content provider的进程,我们希望在某个时刻启用JIT
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}

//在mInstrumentation启动时,在加载任何应用程序代码之前调用。
//通常会被重写调用{@link #start}来开始检测线程,然后将继续在{@link #onStart}中执行。
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}

try {
//调用Application.onCreate()回调方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}

这个方法很长,工作内容如下:

  • 对进程基本参数的设置,比如进程名,时区,资源及兼容性设置;同时添加了对开发者的限制,如不能在主线程使用网络
  • 通过getPackageInfoNoCheck获取LoadedApk对象
  • 实例化ContextImpl,Instrumentation等对象
  • 通过LoadedApk.makeApplication创建应用Application对象
  • 调用Instrumentation.callApplicationOnCreate

4.4.19 AT.getPackageInfoNoCheck()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}

private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
//判断调用方和应用程序是不是同一个用户,如果不是,就不允许跨用户访问
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref;
if (differentUser) {
// 不支持跨用户访问缓存
ref = null;
} else if (includeCode) {
//进入到这个分支,根据应用包名从mPackages获取,也就是说每个app都会拥有唯一的LoadedApk对象
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}

LoadedApk packageInfo = ref != null ? ref.get() : null;
//刚进来这个为null
if (packageInfo == null || (packageInfo.mResources != null
&& !packageInfo.mResources.getAssets().isUpToDate())) {

//创建LoadedApk对象
packageInfo = new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);

if (mSystemThread && "android".equals(aInfo.packageName)) {
packageInfo.installSystemApplicationInfo(aInfo,
getSystemContext().mPackageInfo.getClassLoader());
}

if (differentUser) {
// Caching not supported across users
} else if (includeCode) {
//将新创建的LoadedApk加入到mPackages
mPackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
}
}
return packageInfo;
}
}

这里返回一个LoadedApk对象,这个对象有什么作用呢?

注意:LoadedApk对象是APK文件在内存中的表示,包含apk文件的相关信息,比如应用代码,资源文件,app里的activity和service等都可以从这获取,在使用类加载器的时候需要用到这个对象

4.4.20 LoadedApk.makeApplication()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}

Application app = null;

String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}

try {
//类加载器
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
//创建ContextImpl,在组件中对Context的操作都会转移到这个类
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//创建Application
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
//给mApplication赋值
mApplication = app;

......

SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
.getAssignedPackageIdentifiers();
final int N = packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
//重写所有apk库中的R常量
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}

return app;
}

4.4.21 Instrumentation.newApplication()

1
2
3
4
5
6
7
8
9
10
11
12
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}

这里通过反射实例化Application ,然后调用attach

4.4.22 Application.attach()

1
2
3
4
5
final void attach(Context context) {
//给ContextWrapper对象中指定真正的Context(这里的Context实际类型是ContextImpl )对象
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

4.4.23 ContextWrapper.attachBaseContext()

1
2
3
4
5
6
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}

这里对mBase 进行赋值,实际类型是ContextImpl

4.4.24 Instrumentation.callApplicationOnCreate()

1
2
3
public void callApplicationOnCreate(Application app) {
app.onCreate();
}

4.4.25 Application.onCreate()

1
2
3
4
5
6
7
8
9
/**
* 在应用启动时调用 ,在创建任何activity, service,receiver,content providers之前调用
* 在此方法里操作要尽可能快(比如状态的延迟初始化),因为在这里花费太长时间将会直接影响第一个
* activity, service,receiver,content providers的性能
* 如果重写这个方法,请务必调用super.onCreate()
*/
@CallSuper
public void onCreate() {
}

这里就会回调Application的onCreate方法,我们通常会继承这个类,重写这个方法,做一些APP的初始化操作,但是切记不要做耗时复杂操作,因为这里应用才刚创建,还在初始化,可能会导致应用启动黑屏一段时间的情况

AMS.attachApplicationLocked方法执行完bindApplication后,对照着顶部目录看,接下来就是该方法第七步,启动Activity等操作了

4.4.26 ActivityStackSupervisor.attachApplicationLocked()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
//这里维护着这台设备上所有应用的activitystack,即app的任务栈
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
//取出其中一个任务栈
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFocusedStack(stack)) {
continue;
}
//取出当前任务栈中处于栈顶且运行的activity
ActivityRecord hr = stack.topRunningActivityLocked();
if (hr != null) {
//判断这个activity所在进程是否与当前调用的进程信息是否一致
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
//真正启动activity
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
throw e;
}
}
}
}
}
if (!didSomething) {
//启动失败,需要确保一个可显示的activity
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}

接下来就要真正启动activity了,到这里也快接近尾声了

4.4.27 ActivityStackSupervisor.realStartActivityLocked()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {

//如果activity正在pausing,那就跳过
if (!allPausedActivitiesComplete()) {
return false;
}

if (andResume) {
r.startFreezingScreenLocked(app, 0);
mWindowManager.setAppVisibility(r.appToken, true);
// 启动ticks以收集有关慢速APP的信息。
r.startLaunchTickingLocked();
}

// 让window manager根据新的activity顺序重新评估屏幕方向
if (checkConfig) {
Configuration config = mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false);
}

......

final ActivityStack stack = task.stack;
try {
......

//将该进程设置为前台进程PROCESS_STATE_TOP
app.forceProcessStateUpTo(mService.mTopProcessState);
//启动activity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
// 处理heavy-weight process
if (app.processName.equals(app.info.packageName)) {
if (mService.mHeavyWeightProcess != null
&& mService.mHeavyWeightProcess != app) {
Slog.w(TAG, "Starting new heavy weight process " + app
+ " when already running "
+ mService.mHeavyWeightProcess);
}
mService.mHeavyWeightProcess = app;
Message msg = mService.mHandler.obtainMessage(
ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
msg.obj = r;
mService.mHandler.sendMessage(msg);
}
}

} catch (RemoteException e) {
if (r.launchFailed) {
// 第二次启动失败就放弃 并finish该activity
mService.appDiedLocked(app);
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
}

// 第一次启动失败就重启该进程
app.activities.remove(r);
throw e;
}

r.launchFailed = false;
//将该进程加入到mLRUActivities队列顶部
if (stack.updateLRUListLocked(r)) {
}

......

//更新所有与该Activity具有绑定关系的Service连接
if (r.app != null) {
mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
}

return true;
}

这个方法里这最重要的一步就是app.thread.scheduleLaunchActivity,这里又是一个AIDL实现,app.thread的实际类型是客户端进程在AMS端进程的代理,即ATP;接下来具体过程跟上面分析thread.scheduleExit()的时候一样,这里就不在具体阐述了,直接到ActivityThread

4.4.28 AT.handleLaunchActivity()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
//获取LoadedApk对象
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
}
}
}

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

unscheduleGcIdler();
mSomeActivitiesChanged = true;

if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}

//最终回调目标Activity的onConfigurationChanged()
handleConfigurationChanged(null, null);

// 在创建activity之前初始化wms
WindowManagerGlobal.initialize();
//最终回调目标Activity的onCreate
Activity a = performLaunchActivity(r, customIntent);

if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
//最终回调目标Activity的onStart,onResume
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

} else {
// 如果失败或者其它原因就通知 activity manager 去stop activity.
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}

这里调用了两个关键方法

  • performLaunchActivity
  • handleResumeActivity

4.4.29 AT.performLaunchActivity()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

//获取待启动的Activity的组件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}

Activity activity = null;
try {
//通过类加载器加载activity实例
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}

try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

if (activity != null) {
//创建该activity的context实例,实际类型是ContextImpl
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}

Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
//在这个方法里关联context,并进行Activity一些初始化操作,
//比如完成Window的创建并建立自己和Window的关联
//这样当Window接收到外部输入事件后就可以将事件传递给Activity;
//维护一个Instrumentation引用
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window);

if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
//获取主题并设置
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}

//回调activity的onCreate
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
//如果之前有保存数据,这里回调OnRestoreInstance
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}

}
r.paused = true;

mActivities.put(r.token, r);

} catch (SuperNotCalledException e) {
throw e;

} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}

return activity;
}

4.4.30 AT.handleResumeActivity()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);

......
//见下方
r = performResumeActivity(token, clearHide, reason);

if (r != null) {
final Activity a = r.activity;

final int forwardBit = isForward ?
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

// 如果当前窗口没有添加到 window manager,并且它没有finished或者启动其它activity
// 那就继续添加到 window manager
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
try {
willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient && !a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
}

// 如果该窗口已经添加到了window manager,但是在resume期间,又启动了了一个activity
//那就设置窗口不可见
} else if (!willBeVisible) {
r.hideForNow = true;
}

// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r, false /* force */);

// 如果窗口已经添加,没有finish,没有启动其它activity,那窗口可见
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
r.newConfig = null;
}

//设置输入框显示模式
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
//将当前activity视图设置可见
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}

// 告诉 activity manager 该activity已经 resumed.
if (reallyResume) {
try {
ActivityManagerNative.getDefault().activityResumed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}

} else {
// 当 resume 失败, 就结束这个activity
try {
ActivityManagerNative.getDefault()
.finishActivity(token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}

4.4.31 AT.performResumeActivity()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide, String reason) {
ActivityClientRecord r = mActivities.get(token);

if (r != null && !r.activity.mFinished) {
if (clearHide) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
try {
r.activity.onStateNotSaved();
r.activity.mFragments.noteStateNotSaved();
if (r.pendingIntents != null) {
//回调onNewIntent
deliverNewIntents(r, r.pendingIntents);
r.pendingIntents = null;
}
if (r.pendingResults != null) {
//回调onActivityResult
deliverResults(r, r.pendingResults);
r.pendingResults = null;
}
//在这里相继回调onStart onResume
r.activity.performResume();
......

r.paused = false;
r.stopped = false;
r.state = null;
r.persistentState = null;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to resume activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
return r;
}

到这里一个Activity就从无到有被启动且可见了

4.5 流程图

参考文档

从源码解析Android中Zygote进程是如何fork一个APP进程的

Android 10.0系统启动之init进程-[Android取经之路]

从源码解析-Android系统启动流程概述 init进程zygote进程SystemServer进程启动流程

Android zygote 进程的启动过程分析

APP启动流程解析

ActivityThrad的工作逻辑