foreword
Are you confused about the relationship between the major processes of the Android system, such as Zygote, init, and SystemServer processes, as well as the key services of Android, AMS, and ServiceManager? Always remembering and forgetting, it is difficult to form a complete structure in the brain? This article allows you to see the operation of the system through a few simple shell commands, so that you can have an intuitive feeling of the process threads in the system, which is convenient for you to further analyze the source code of major services in the future.
List of important Android processes
First execute the adb devices
command in the terminal to make sure that you are connected to a virtual machine or real machine and online, and then execute the adb shell ps
command to see all the running processes of the current device. The table below lists only some of the processes we are familiar with.
USER | PID | PPID | NAME |
---|---|---|---|
root | 1 | 0 | heat |
root | 151 | 1 | heat |
root | 312 | 1 | Zygote64 |
system | 179 | 1 | servicemanager |
system | 180 | 1 | hwservicemanager |
system | 511 | 312 | system_server |
shell | 4149 | 1745 | ps |
- USER represents the current user of the process. root is the built-in superuser of Linux, while system is the Android system user.
- PID stands for the ID of the process.
- PPID stands for the parent process ID, which is the process ID that created the process. It can be clearly seen here that Linux created a
init
process, the init process created another processZygote64
,servicemanager
and the Zygote process created anothersystem_server
process.
Execution
adb shell
After entering the shell and then executing theps
command may not be the same as the result you see, that is because the shell terminal used is different, andps -A
you can see the complete command by using the command at this time. The shell terminal in the computer is used to execute theadb shell ps
command directly, andadb shell
the shell entered by the execution is the shell terminal in the device.
List of threads under the init process
执行adb shell ps -T 1
命令即可查看PID为1的进程下的所有线程。
USER | PID | TID | PPID | CMD |
---|---|---|---|---|
root | 1 | 1 | 0 | init |
root | 1 | 150 | 0 | init |
执行adb shell ps -T 151
命令即可查看PID为151的进程下的所有线程。
USER | PID | TID | PPID | CMD |
---|---|---|---|---|
root | 151 | 151 | 1 | init |
- PID代表进程的ID。
- TID代表线程ID。
- PPID代表父进程ID,即创建该进程的进程ID。
并不了解为何系统会有两个init进程、三个init线程,如果后续了解到会再补充。
Zygote64进程下线程一览
执行adb shell ps -T 312
命令即可查看PID为312的进程下的所有线程。所有的应用进程都是通过Zygote进程fork出来的子进程,所以他所有的线程都会在应用线程创建的时候就存在。
USER | PID | TID | PPID | CMD |
---|---|---|---|---|
root | 312 | 312 | 1 | main |
root | 312 | 7390 | 1 | Jit thread pool |
root | 312 | 7391 | 1 | HeapTaskDaemon |
root | 312 | 7392 | 1 | ReferenceQueueD |
root | 312 | 7393 | 1 | FinalizerDaemon |
root | 312 | 7394 | 1 | FinalizerWatchd |
main
即通常所说的主线程。Jit thread pool
不认识,暂时没在源码里查到HeapTaskDaemon
用于释放堆内存即通常说的GCReferenceQueueDaemon
负责软、弱、虚引用的对象的回收FinalizerDaemon
用来回调【即将被回收的对象】的finalize方法;FinalizerWatchdogDaemon
监视FinalizerDaemon线程,如果在回调【即将被回收的对象】的finalize方法时超过了100_0000_0000纳秒(即10秒),那么进程会被强行kill掉
ServiceManager进程下线程一览
执行adb shell ps -T 179
命令即可查看PID为179的进程下的所有线程。可以看到ServiceManager进程下仅有一个同名线程,说明ServiceManager线程专门用于Binder服务的管理。
USER | PID | TID | PPID | CMD |
---|---|---|---|---|
system | 179 | 179 | 1 | servicemanager |
SystemServer进程下线程一览
执行adb shell ps -T 511
命令即可查看PID为511的进程下的所有线程。SystemServer进程下有多达150个线程,这里仅列举出部分我们熟悉的线程。这里可以看到有:
- 1个
ActivityManagerService
线程,这是ActivityManagerService所使用的线程。 - 4个
ActivityManager
线程,暂时不知道干嘛的。 android.anim
主要工作:Choreographer运行在这个线程中,负责协调动画相关内容。android.anim.lf
主要工作:负责协调SurfaceAnimation动画相关内容。android.bg
所有线程共享的一个后台线程,本身并不包含处理任务的代码,具体的工作由Runnable或者Handler完成。TODO 具体工作内容还需进一步分析。android.display
线程,主要用于:- DisplayManagerService(display adapter,viewport ,event…)
- InputManagerService (keyboard , input device …)
- WindowManagerService 实例的创建
android.fg
一个共享前台线程,源代码为FgThread.java,主要用于:- AccountManagerService
- BatteryStatsService
- DreamManagerService
- MountService
- NetworkManagementService
- PackageManagerService
- usb相关(debug, device, portmanager)
- WindowManagerService(screenshotApplicationsInner)
android.io
线程,主要有用于:- BluetoothManagerService 相关操作
- MountService里的obb操作
- Tethering 网络共享(usb /wifi/mobile?)
- TvInputManagerService tv里channel session相关
android.ui
主要处理:- AMS UiHandler里show各种msg
- DisplayManagerService里的overlay相关msg
- PointerEventDispatcher inputevent相关
- VoiceInteractionManagerService Voice交互
- WindowManagerPolicy init操作
AsyncTask #1
是我们的AsyncTask所使用的线程。查看AsyncTask源码可知AsyncTask最多可同时启动20个线程,但空闲时只保留1个线程。当然不一定是保留编号为1的线程,所以#后面跟的编号并不一定是1。
WARNING:新版本谷歌已经将AsyncTask废弃并建议用户使用Concurrent并发包。Binder:511_1~Binder:511_20
SystemServer所使用的Binder线程池,9.0源码里SystemServer的Binder线程数量最多为31个。但小米手机里的有32个,暂时不清楚为什么……queued-work-looper
异步任务所使用的线程,最著名的使用方法是SharedPreference的Apply方法。
USER | PID | TID | PPID | CMD |
---|---|---|---|---|
system | 511 | 612 | 312 | AccountManagerS |
system | 511 | 556 | 312 | ActivityManager |
system | 511 | 557 | 312 | ActivityManager |
system | 511 | 558 | 312 | ActivityManager |
system | 511 | 559 | 312 | ActivityManager |
system | 511 | 1766 | 312 | AdbDebuggingMan |
system | 511 | 615 | 312 | AlarmManager |
system | 511 | 535 | 312 | android.anim |
system | 511 | 536 | 312 | android.anim.lf |
system | 511 | 543 | 312 | android.bg |
system | 511 | 534 | 312 | android.display |
system | 511 | 531 | 312 | android.fg |
system | 511 | 533 | 312 | android.io |
system | 511 | 532 | 312 | android.ui |
system | 511 | 583 | 312 | AsyncTask #1 |
system | 511 | 666 | 312 | AudioService |
system | 511 | 529 | 312 | Binder:511_1 |
…… | …… | …… | …… | …… |
system | 511 | 2266 | 312 | Binder:511_20 |
system | 511 | 616 | 312 | CameraService_p |
system | 511 | 564 | 312 | FileObserver |
system | 511 | 520 | 312 | HeapTaskDaemon |
system | 511 | 541 | 312 | HwBinder:511_1 |
…… | …… | …… | …… | …… |
system | 511 | 815 | 312 | HwBinder:511_5 |
system | 511 | 519 | 312 | Jit thread pool |
system | 511 | 585 | 312 | PackageInstalle |
system | 511 | 575 | 312 | PackageManager |
system | 511 | 577 | 312 | PackageManager |
system | 511 | 574 | 312 | PackageManagerB |
system | 511 | 3726 | 312 | queued-work-loo |
system | 511 | 696 | 312 | SyncManager |
system | 511 | 560 | 312 | Thread-2 |
system | 511 | 567 | 312 | Thread-3 |
system | 511 | 568 | 312 | Thread-4 |
system | 511 | 570 | 312 | Thread-5 |
system | 511 | 569 | 312 | Thread-6 |
system | 511 | 669 | 312 | Thread-10 |
system | 511 | 685 | 312 | Thread-11 |
system | 511 | 846 | 312 | Thread-13 |
部分资料来源:System server里创建常见的几个thread
附加题 Hello World应用进程创建后有多少个线程
可以看到除了从Zygote继承过来的6个线程之外,系统还为进程创建了Signal Catcher
、Profile Saver
、 RenderThread
以及3个Binder构成的线程池。
Signal Catcher
源代码在signal_catcher.cc,具体的启动方式是在runtime.cc的InitNonZygoteOrPostFork方法中启动的,参见SignalCatcher的线程启动。此进程主要功能:一是打印当前进程的堆栈(Java、Native、Kernel),同时把当前虚拟机的一些状态信息也打印出来,并保存在traces.txt文件中;二是进行进程的强制GC并保存GC的profile信息。Profile Saver
Profile收集线程,源代码在profile_saver.cc,用于更新app的profile文件,指导dex2oat如何将dex编译成oat文件。Android profile-guided dex2oatRenderThread
渲染线程,Android 5.0之后,Android应用程序的Open GL线程从主线程中独立出来,称为Render Thread。源代码在RenderThread.cpp,具体主线程和渲染线程的分工可以看Android Systrace 基础知识 - MainThread 和 RenderThread 解读。如果你在应用的Application标签下配置android:hardwareAccelerated="false"关闭默认开启的硬件加速则不会有此线程。
USER | PID | TID | PPID | CMD |
---|---|---|---|---|
u0_a169 | 6401 | 6401 | 291 | pty_application |
u0_a169 | 6401 | 6411 | 291 | Signal Catcher |
u0_a169 | 6401 | 6414 | 291 | Jit thread pool |
u0_a169 | 6401 | 6415 | 291 | HeapTaskDaemon |
u0_a169 | 6401 | 6416 | 291 | ReferenceQueueD |
u0_a169 | 6401 | 6417 | 291 | FinalizerDaemon |
u0_a169 | 6401 | 6418 | 291 | FinalizerWatchd |
u0_a169 | 6401 | 6419 | 291 | Binder:6401_1 |
u0_a169 | 6401 | 6420 | 291 | Binder:6401_2 |
u0_a169 | 6401 | 6421 | 291 | Binder:6401_3 |
u0_a169 | 6401 | 6423 | 291 | Profile Saver |
u0_a169 | 6401 | 6424 | 291 | RenderThread |
总结
此次研究仅是对Android系统内部的进程和线程有了一个初步的了解。相对于其他文章的源代码分析、调用链分析,直接的查看系统当前进程、线程运行情况能让初学者对线程和进程的关系、Android启动过程中进程的创建流程有一个更直观的了解。本文适合作为Android各大服务源代码分析的前置文章,仅供各位参考,文章中有任何讹误欢迎在评论区指出,感谢!