简介
架构图一
架构图二
架构解析
- Linux内核层:包含Linux内核和驱动模块(比如USB、Camera、蓝牙等)。
- Libraries层:这一层提供动态库、android运行时库、虚拟机,这一层大部分都是C/C++写的,还有一些三方库比如SQLite, WebKit。
- 硬件抽象层 (HAL):硬件抽象层 (HAL) 提供标准接口,HAL包含多个库模块,其中每个模块都为特定类型的硬件组件实现一组接口,比如WIFI/蓝牙模块,当框架API请求访问设备硬件时,Android系统将为该硬件加载相应的库模块。
- FrameWork层:它是android平台上Java世界的基石,这一层大部分用Java写的,包括系统服务和四大组件。
- Applications层:我们开发的就是应用层,不仅包括通话短信联系人这种系统级的应用,还包括用户自己安装的一些第三方应用。
系统编译
- 下载源码
- 查看源码(Source Insight)
- 编译源码(Ubuntu/Mac OS)
- 系统
系统启动
Bootloader
当按下电源键(加电)或者系统重启(复位)的时候,引导芯片会从 ROM(这里一般指 Flash ROM,即闪存)中预定义的位置将 Bootloader 载入到 RAM 中,接着,Bootloader 将会把 Linux 内核载入到 RAM 中并启动。
Bootloader 是在系统内核运行之前运行的一段小程序,也是系统运行的第一个程序,它的主要作用是
- 初始化 RAM(一般指内存)
- 初始化硬件设备
- 加载内核和内存空间影像图
- 跳转到内核
init
Linux 内核启动过程中会创建 init 进程,init 进程是用户空间的第一个进程(pid=1),对应的可执行程序的源文件文件为 /system/core/init/Init.cpp,它的 main 方法如下:
1 | int main(int argc, char** argv) { |
解析和运行所有 init.rc 文件
rc 文件由 Android 初始化语言编写,rc 文件主要包含 Action、Service、Command、Options 等,这些操作都由特殊的命令组成。
1 | import /init.environ.rc |
在开头几行代码中,import 导入了几个 rc 文件,事实上,在 system/core/rootdir 目录下,有多个 init.XXX.rc 文件,在不同的硬件环境下,相应的 init.XXX.rc 文件会被导入,比如在 64 位操作系统中,init.zygote64.rc 文件将会被导入,它的内容如下:
1 | service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server |
这几行代码表示启动一个名字为 zygote、 执行文件路径为 /system/bin/app_process64、参数为 -Xzygote /system/bin –zygote –start-system-server 的进程。
除了 zygote 进程,还有许多关键进程都是由 init 进程通过读取相应的 rc 文件进行启动的,如 servicemanager、surfaceflinger 和 mediaserver 进程等等,这些进程都是保证系统运行必不可少的。
servicemanager进程- Binder 服务的总管
Binder 通信模型和通信过程”的时候提到过 ServerManager,它是 Binder IPC 的核心,是上下文的管理者,Binder 服务端必须先向 ServerManager 注册才能够为客户端提供服务,Binder 客户端在与服务端通信之前需要从 ServerManager 中查找并获取 Binder 服务端的引用。
servicemanager 进程是通过解析 servicemanager.rc 文件来启动的,对应的代码如下:
1 | service servicemanager /system/bin/servicemanager |
servicemanager 进程对应可执行程序的源文件为
framework/native/cmds/servicemanager/service_manager.c,简化后的代码如下:
1 | int main(int argc, char **argv) { |
- servicemanager 进程在启动过程的工作内容如下:
- 调用 binder_open 方法打开 Binder 驱动,并申请分配一块 128k 的内存空间
- 调用 binder_become_context_manager 方法发送 BINDER_SET_CONTEXT_MGR 给 Binder 驱动,使自己成为上下文管理者
- 验证 selinux 权限,判断进程是否有注册或查看指定服务的权限
- 调用 binder_loop 方法进入循环状态,等待 Client 请求
- 根据服务名称注册服务·
- 接收 Binder 死亡通知
zygote进程- Java 进程的始祖
通过解析 init.rc 文件, zygote 进程对应的可执行程序的源文件为 frameworks/base/cmds/app_process/App_main.cpp,它的 main 方法如下:
1 | int main(int argc, char* const argv[]) |
调用 frameworks/base/core/jni/AndroidRuntime.cpp 的 start 方法:
1 | void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) |
通过 JNI 的方式进入 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:
1 | public static void main(String argv[]) { |
ZygoteInit.java 的 registerZygoteSocket 方法:
1 | private static void registerZygoteSocket(String socketName) { |
ZygoteInit.java 的 startSystemServer 方法:
1 | private static boolean startSystemServer(String abiList, String socketName) |
可以看到,这个过程中 zygote 首先启动了 AndroidRuntime 并通过它反射调用了 ZygoteInit.main() 方法,由此进入了 Java 的世界,因此 zygote 是 Java 层的第一个进程,也是其他 Java 进程的始祖,其他 Java 进程的创建必须依赖 zygote。
zygote 进程的任务分别是:
- 1.创建 AppRuntime(继承自 AndroidRuntime), 并调用它的 start 方法
- 2.调用 AndroidRuntime 的 startVM() 方法创建 DVM(Dalvik Virtual Machine),并调用 startReg() 方法为 DVM 注册 JNI
- 3.通过 JNI 调用 ZygoteInit.main() 方法,第一次进入 Java 的世界
- 4.调用 registerZygoteSocket() 函数建立 Socket 通道,使 zygote 进程成为 Socket 服务端,并通过 runSelectLoop() 函数等待 ActivityManagerService 发送请求创建新的应用程序进程
- 5.调用 startSystemServer() 函数 fock 出 system_server 进程
system_server进程 — 承载 framework 层核心业务
zygote 进程在启动的过程中会通过 startSystemServer 方法 fock 出了一个叫 system_server 的进程,然后再该方法内执行了 handleSystemServerProcess 方法:
1 | private static void handleSystemServerProcess( |
RuntimeInit.java 的 zygoteInit 方法:
1 | public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) |
RuntimeInit 的 applicationInit 方法:
1 | private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) |
RuntimeInit 的 invokeStaticMain 方法:
1 | private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) |
ZygoteInit.java 的 main 方法:
1 | public static void main(String argv[]) { |
ZygoteInit 的 MethodAndArgsCaller 类是一个 Exception 类,同时也实现了 Runnable 接口:
1 | public static class MethodAndArgsCaller extends Exception |
这样,system_server 进程便启动起来并进入了 SystemServer.java 的 main 方法。
system_server 进程的执行过程
1 | /** |
可以看到,在 run 方法中,主要执行了启动引导服务、核心服务和其他服务的任务,这些服务加起来一共有 80 多个,它们对应这个各种不同的功能,比如常用的ActivityManagerService、PowerManagerService、PackageManagerService、CameraService等等。
Launcher —— Android 系统的“桌面”
SystemServer.java 的 main 方法中,有一句:
1 | private void startOtherServices() { |
继续跟踪:ActivityManagerService.java:
1 | public void systemReady(final Runnable goingCallback) { |
继续跟踪:ActivityStackSupervisor.java:
1 | boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, |
继续跟踪:ActivityStack:
1 | boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { |
继续跟踪:ActivityStackSupervisor:
1 | boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) { |
最后通过一个隐式 Intent 使用 Intent.FLAG_ACTIVITY_NEW_TASK 模式启动了一个带 Intent.CATEGORY_HOME 标签的 Activity,而带有 Intent.CATEGORY_HOME 标签的 Activity 正是 Launcher App,它的 AndroidManifest 文件如下:
1 | <manifest |
总结
- 按下电源,固化在 ROM 中预定位置的 Bootloader 将会被加载到内存中
- Bootloader 初始化完软硬件环境后将 Linux 内核启动起来
- 内核启动完成后会启动 init 进程
- init 进程会初始化并启动属性服务,并且解析并执行所有 init.rc 文件
- init 通过执行特定的 init.rc 文件启动 servermanager 进程,servermanager 被启动后会向 Binder 驱动发送命令让自己成为守护进程并管理所有上下文
- init 通过解析 init.rc 文件启动 zygote 进程
- zygote 进程启动的过程会创建 DVM 并为其注册 JNI 函数,然后创建服务端 Socket、启动 system_server 进程
- 启动 system_server 进程的过程会创建 Binder 线程池使其具有 IPC 能力,然后启动 AMS 等各种系统服务
- AMS 启动 Launcher,Launcher 被启动后会将已安装应用的图标显示在界面上