~Android启动过程
安卓系统启动
Android系统底层基于Linux Kernel,当Kernel启动过程会创建init进程,该进程是所有用户空间的鼻祖,init进程会启动servicemanager(binder服务管家),Zygote进程(Java进程的鼻祖)。Zygote进程会创建system_server进程以及各种app进程,下图是这几个系统重量级进程之间的层级关系。
init进程
init是Linux系统中用户空间的第一个进程(pid=1),Kerner启动后会调用/system/core/init/Init.cpp的main()方法。
Zygote
当Zygote进程启动后,便会执行到frameworks/base/cmds/app_process/App_main.cpp文件的main()方法。
Zygote进程创建Java虚拟机,并注册JNI方法,真正成为Java进程的母体,用于孵化Java进程。在创建完system_server进程后,调用runSelectLoop(),随时待命,当接收到创建新进程请求时立即唤醒并执行相应工作。
system_server
Zygote通过fork后创建system_server进程,system_server主线程的启动工作完成後,进入Looper.loop()状态,等待其他线程通过Handler发送消息再处理。
App
对于普通的App进程,跟system_server进程的启动过来有些类似。不同的是App进程是向发消息给system_server进程,由system_server向Zygote发出创建进程的请求。
启动日志分析
以下列举启动部分重要进程以及关键节点会打印出的log:
/system/bin/vold: 383
/system/bin/lmkd: 432
/system/bin/surfaceflinger: 434
/system/bin/debuggerd64: 537
/system/bin/mediaserver: 540
/system/bin/installd: 541
/system/vendor/bin/thermal-engine: 552
zygote64: 557
zygote: 558
system_server: 1274
通过adb bugreport抓取log信息。先看Zygote是否起来,再看system_server主线程的运行情况,再看ActivityManager情况:
1 | |
现场调试命令:
"cat proc/[pid]/stack"==> 查看kernel调用栈"debuggerd -b [pid]"==> 也不可以不带参数-b,则直接输出到/data/tombstones/目录"kill -3 [pid]"==> 生成/data/anr/traces.txt文件"lsof [pid]"==> 查看进程所打开的文件
总结
各大核心进程启动后,都会进入其所相应的main()函数,如下:
| 进程 | 主函数 |
|---|---|
| init进程 | Init.main() |
| Zygote进程 | ZygoteInit.main() |
| app_process进程 | RuntimeInit.main() |
| system_server进程 | SystemServer.main() |
| App进程 | ActivityThread.main() |
注意:app_process进程是指通过/system/bin/app_process启动的进程,并非启动zygote进程。比如通过adb shell执行am,pm等命令,便是这种方式。
关于重要进程重启的过程,会触发哪些关联进程:
- Zygote: 触发media,netd以及子进程(包括system_server进程)重启;
- system_server: 触发Zygote重启;
- surfaceflinger:触发Zygote重启;
- servicemanager: 触发Zygote,healthd,media,surfaceflinger,drm重启
surfaceflinger,servicemanager,zygote自身以及system_server进程被杀都会触发Zygote重启。