Android系统非常庞大、错综复杂,其底层是采用Linux
作为基底,上层采用包含虚拟机的Java层以及Native
层,通过系统调用(Syscall)连通系统的内核空间与用户空间。用户空间主要采用C++和Java代码,通过JNI
技术打通用户空间的Java层和Native
层(C++/C),从而融为一体。
Google官方提供了一张经典的四层架构图,从下往上依次分为Linux内核、系统库和Android运行时环境、框架层以及应用层这4层架构,其中每一层都包含大量的子模块或子系统。这只是如垒砖般地分层,并没有表达Android整个系统的内部架构、运行机理,以及各个模块之间是如何衔接与配合工作的。为了更深入地掌握Android整个架构思想以及各个模块在Android系统所处的地位与价值,计划以Android
系统启动过程为主线,以进程的视角来诠释Android M系统全貌,全方位的深度剖析各个模块功能,争取各个击破。这样才能犹如庖丁解牛,解决、分析问题则能游刃有余。
android-arch1
Google提供的4层架构图很经典,但为了更进一步透视Android系统架构,本文更多的是以进程的视角,以分层的架构来诠释Android系统的全貌,阐述Android内部的环环相扣的内在联系。
图解: Android系统启动过程由上图从下往上的一个过程:Loader -> Kernel -> Native -> Framework -> App
,接来下简要说说每个过程:
Boot ROM
: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设出代码开始执行,然后加载引导程序到RAM;
Boot Loader
:这是启动Android系统之前的引导程序,主要是检查RAM
,初始化硬件参数等功能。
Kernel
层是指Android内核层,到这里才刚刚开始进入Android系统。
启动Kernel
的swapper
进程(pid=0
):该进程又称为idle
进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver
等相关工作;
启动kthreadd
进程(pid=2
):是Linux系统的内核进程,会创建内核工作线程kworkder
,软中断线程ksoftirqd
,thermal
等内核守护进程。kthreadd
进程是所有内核进程的鼻祖。
这里的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
进程的父进程,Zygote
进程本身是由init
进程孵化而来的。Framework
层Zygote
进程,是由init
进程通过解析init.rc
文件后fork
生成的,Zygote
进程主要包含:
ZygoteInit
类,注册Zygote Socket
服务端套接字;preloadClasses
;preloadResouces
。System Server
进程,是由Zygote
进程fork
而来,System Server
是Zygote
孵化的第一个进程,System Server
负责启动和管理整个Java framework
,包含ActivityManager
,PowerManager
等服务。
Media Server
进程,是由init
进程fork
而来,负责启动和管理整个C++ framework
,包含AudioFlinger
,Camera Service
,等服务。
Zygote
进程孵化出的第一个App
进程是Launcher
,这是用户看到的桌面App
;
Zygote
进程还会创建Browser
,Phone
,Email
等App
进程,每个App
至少运行在一个进程上。
所有的App
进程都是由Zygote
进程fork
生成的。
Syscall
&& JNI
Native
与Kernel
之间有一层系统调用(SysCall
)层,见Linux系统调用(Syscall
)原理;
Java层与Native
(C/C++)层之间的纽带JNI
,见Android JNI
原理分析。
无论是Android系统,还是各种Linux衍生系统,各个组件、模块往往运行在各种不同的进程和线程内,这里就必然涉及进程/线程之间的通信。对于IPC
(Inter-Process Communication
, 进程间通信),Linux现有管道、消息队列、共享内存、套接字、信号量、信号这些IPC
机制,Android额外还有Binder IPC
机制,Android OS中的Zygote
进程的IPC
采用的是Socket
机制,在上层system server、media server
以及上层App之间更多的是采用Binder IPC
方式来完成跨进程间的通信。对于Android上层架构中,很多时候是在同一个进程的线程之间需要相互通信,例如同一个进程的主线程与工作线程之间的通信,往往采用的Handler
消息机制。
想深入理解Android内核层架构,必须先深入理解Linux现有的IPC
机制;对于Android上层架构,则最常用的通信方式是Binder、Socket、Handler
,当然也有少量其他的IPC
方式,比如杀进程Process.killProcess()
采用的是signal
方式。下面说说Binder、Socket、Handler
:
Binder
作为Android系统提供的一种IPC
机制,无论从系统开发还是应用开发,都是Android系统中最重要的组成,也是最难理解的一块知识点,想了解为什么Android要采用Binder
作为IPC
机制? 可查看我在知乎上的回答。深入了解Binder
机制,最好的方法便是阅读源码,借用Linux鼻祖Linus Torvalds曾说过的一句话:Read The Fucking Source Code
。下面简要说说Binder IPC
原理。
Binder IPC原理
Binder
通信采用c/s架构,从组件视角来说,包含Client、Server、ServiceManager
以及binder
驱动,其中ServiceManager
用于管理系统中的各种服务。
ServiceManager
想进一步了解Binder
,可查看Binder
系列—开篇,Binder
系列花费了13篇文章的篇幅,从源码角度出发来,讲述Driver、Native、Framework、App
四个层面的整个完整流程。根据有些读者反馈这个系列还是不好理解,这个binder
涉及的层次跨度比较大,知识量比较广, 建议大家先知道binder
是用于进程间通信,有个大致概念就可以.先去学习系统基本知识,等后面有一定功力再进一步深入研究Binder
.
原理篇
序号 | 文章名 | 概述 |
---|---|---|
0 | Binder系列—开篇 | 概述Binder |
1 | Binder系列3—启动Service Manager | ServiceManager守护进程 注册和查询服务 |
2 | Binder系列4—获取Service Manager | 获取代理对象BpServiceManager |
3 | Binder系列5—注册服务(addService) | 注册Media服务 |
4 | Binder系列6—获取服务(getService) | 获取Media代理,以及DeathRecipient |
5 | Binder系列7—framework层分析 | framework层服务注册和查询,Binder注册 |
6 | Binder系列—理解Binder线程池的管理 | Binder的startThreadPool过程 |
7 | Binder系列—彻底理解Android Binder通信架构 | startService为主线 |
8 | Binder系列10—总结 | Binder的简单总结 |
9 | Binder IPC的权限控制 | clearCallingIdentity/restoreCallingIdentity |
驱动篇:
序号 | 文章名 | 概述 |
---|---|---|
1 | Binder系列1—Binder Driver初探 | 驱动open/mmap/ioctl,以及binder结构体 |
2 | Binder系列2—Binder Driver再探 | Binder通信协议,内存机制 |
使用篇:
序号 | 文章名 | 概述 |
---|---|---|
1 | Binder系列8—如何使用Binder | Native层、Framwrok层自定义Binder服务 |
2 | Binder系列9—如何使用AIDL | App层自定义Binder服务 |
Socket
Socket
通信方式也是C/S
架构,比Binder
简单很多。在Android系统中采用Socket
通信方式的主要:
zygote
:用于孵化进程,系统进程system_server
孵化进程时便通过socket
向zygote
进程发起请求;installd
:用于安装App的守护进程,上层PackageManagerService
很多实现最终都是交给它来完成;lmkd
:lowmemorykiller
的守护进程,Java层的LowMemoryKiller
最终都是由lmkd
来完成;adbd
:这个也不用说,用于服务adb
;logcatd
:这个不用说,用于服务logcat
;vold
:即volume Daemon
,是存储类的守护进程,用于负责如USB
、Sdcard
等存储设备的事件处理。等等还有很多,这里不一一列举,Socket
方式更多的用于Android framework
层与native
层之间的通信。Socket
通信方式相对于binder
非常简单,所以一直没有写相关文章,为了成一个体系,下次再补上。
Binder/Socket
用于进程间通信,而Handler
消息机制用于同进程的线程间通信,Handler
消息机制是由一组MessageQueue、Message、Looper、Handler
共同组成的,为了方便且称之为Handler
消息机制。
有人可能会疑惑,为何Binder/Socket
用于进程间通信,能否用于线程间通信呢?答案是肯定,对于两个具有独立地址空间的进程通信都可以,当然也能用于共享内存空间的两个线程间通信,这就好比杀鸡用牛刀。接着可能还有人会疑惑,那handler
消息机制能否用于进程间通信?答案是不能,Handler
只能用于共享内存地址空间的两个线程间通信,即同进程的两个线程间通信。很多时候,Handler
是工作线程向UI
主线程发送消息,即App应用中只有主线程能更新UI
,其他工作线程往往是完成相应工作后,通过Handler
告知主线程需要做出相应地UI更新操作,Handler
分发相应的消息给UI
主线程去完成,如下图:
handler_communication
由于工作线程与主线程共享地址空间,即Handler
实例对象mHandler
位于线程间共享的内存堆上,工作线程与主线程都能直接使用该对象,只需要注意多线程的同步问题。工作线程通过mHandler
向其成员变量MessageQueue
中添加新Message
,主线程一直处于loop()
方法内,当收到新的Message
时按照一定规则分发给相应的handleMessage()
方法来处理。所以说,而Handler
消息机制用于同进程的线程间通信的核心是线程间共享内存空间,而不同进程拥有不同的地址空间,也就不能用handler
来实现进程间通信。
上图只是Handler消息机制的一种处理流程,是不是只能工作线程向UI主线程发消息呢,其实不然,可以是UI线程向工作线程发送消息,也可以是多个工作线程之间通过handler发送消息。更多关于Handler消息机制文章:
Android消息机制-Handler(framework篇)
Android消息机制-Handler(native篇)
Android消息机制3-Handler(实战)
要理解framework
层源码,掌握这3种基本的进程/线程间通信方式是非常有必要,当然Linux还有不少其他的IPC
机制,比如共享内存、信号、信号量,在源码中也有体现,如果想全面彻底地掌握Android系统,还是需要对每一种IPC
机制都有所了解。
2016年新的一年刚开始,首先祝大家、也祝自己在新的一年诸事顺心,事业蒸蒸日上。在过去的一年,对于Android从底层一路到上层有不少自己的理解和沉淀,但总体较零散,未成体系。借着今天(元旦假日的最后一天),给自己的新的一年提前做一个计划,把知识进行归档整理与再学习,从而加深对Android
架构的理解。通过前面对系统启动的介绍,相信大家对Android系统有了一个整体观,接下来需要抓核心、理思路,争取各个击破。
计划:不少文章还没来得及进一步加工,大篇章的源码,有读者跟我反馈看着发困,先别急,文章还会不断更新和升级。前期计划先将系统所有核心技术点的边整理边写博客; 后期工作有时间再根据大家的反馈以及自己的校验,再不断修正和完善所有文章,争取给文章,再进一步精简非核心代码,增加可视化图表以及文字的结论性分析。
博客定位: 基于Android 6.0的源码,专注于分享Android系统原理、架构分析的原创文章。
建议阅读群体: 适合于正从事或者有兴趣研究Android系统的工程师或者爱好者,也适合Android app高级工程师; 对于尚未入门或者刚入门的app程序员阅读可能会困难些,可能不是很适合。
看到Android整个系统架构是如此庞大的, 该问如何学习Android系统, 以下是我自己琢磨的Android的学习和研究论,仅供参考:如何自学Android.
Android系统启动-概述: Android系统中极其重要进程:init, zygote, system_server, servicemanager
进程:
再来看看守护进程(进程名一般以d
为后缀,比如logd
), 先介绍以下部分,后缀再增加.
debuggerd
installd
lmkd
Android系稳定性主要是异常崩溃(crash
)和执行超时(timeout
), Android系统稳定性简述 :
进程对于系统非常重要,系统运转,各种服务、组件的载体都依托于进程,对进程理解越深刻,越能掌握系统整体架构。那么先来看看进程相关:
对于App来说,Android应用的四大组件Activity,Service,Broadcast Receiver,Content Provider
最为核心,接下分别展开介绍:
图形也是整个系统非常复杂且重要的一个系列,涉及WindowManager
,SurfaceFlinger
.
再则就是在整个架构中有大量的服务,都是基于Binder
来交互的,计划针对部分核心服务来重点分析:
最后,说说Android相关的一些常用命令和工具以及调试手段.
计划: 后续持续新增和完善整个大纲,不限于进程、内存、IO、系统服务框架,整体架构以及各种系统分析实战等文章。 博客会持续更新,各个击破,本文最近更新时间点: 2017.09.03.