一、Android系统架构概览:从底层到应用的全景图

各位同学,今天我们来聊聊Android系统架构。说实话,这个主题我讲了不下几十次,但每次讲都有新感悟。Android系统不是一块铁板,而是像千层蛋糕一样,一层叠一层。每一层都有自己的职责,层与层之间通过特定的接口通信。

我个人习惯把Android系统比作一家公司:Linux内核是基层员工,负责干苦活累活;HAL是部门经理,把底层细节包装好;系统服务是总监,协调各个部门;应用框架是公司前台,接待外部访客;应用层就是客户,只管提需求。这个比喻虽然简单,但很形象。

1.1 五层架构总览

Android系统从下到上分为五层,每一层都不可或缺。我刚开始学Android时,总觉得只要会写Java代码就够了。后来踩了不少坑才明白——不懂底层,上层出了问题你连排查方向都没有。

层级 核心组件 主要职责
应用层 系统应用、第三方应用 用户直接交互的界面和功能
应用框架层 ActivityManager、WindowManager等 提供应用开发API,管理应用生命周期
系统服务层 System Server、各种Service 核心服务运行,如AMS、WMS、PMS
硬件抽象层HAL Camera HAL、Audio HAL等 屏蔽硬件差异,提供统一接口
Linux内核层 驱动、进程管理、内存管理 硬件驱动、系统底层支持

嗯,这里要注意:很多人以为Android就是Java写的,其实底层C/C++占了很大比重。你想想看,如果全部用Java,那些硬件驱动怎么跑?

1.2 各层职责与交互机制

每一层都不是孤岛。它们通过Binder、Socket、共享内存等方式通信。我曾在项目中遇到过一个问题:应用层调用相机拍照,结果黑屏。排查了半天,发现是HAL层的Camera HAL返回了错误数据。这就是典型的跨层问题。

Linux内核层:负责进程调度、内存管理、网络协议栈、安全模型等。Android基于Linux,但做了大量定制。比如wakelock机制,就是Android独有的。我曾经因为wakelock没处理好,导致设备无法深度休眠,一晚上耗电30%。

硬件抽象层HAL:说白了,就是给上层一个标准接口,不管底层是高通还是联发科的芯片,上层调用方式都一样。HAL以so库的形式存在,由系统服务层加载调用。

系统服务层:这是Android的核心。System Server进程启动后,会创建AMS、WMS、PMS等上百个服务。这些服务运行在独立的进程中,通过Binder与上层通信。我建议初学者重点研究AMS和WMS,这两个是理解Android的钥匙。

应用框架层:提供四大组件、资源管理、通知管理等API。你写的App就是调用这些API来工作的。框架层封装了底层复杂性,让开发者专注于业务逻辑。

应用层:用户直接接触的部分。系统应用如电话、短信、设置,以及你开发的第三方应用。

核心要点:层与层之间通过Binder IPC通信。Binder是Android独有的进程间通信机制,效率高、安全性好。理解Binder是理解Android Framework的关键。

1.3 架构分层示意图

下面这张图是我手绘的架构分层图,展示了各层之间的调用关系。注意看箭头方向——上层调用下层,下层通过回调或广播通知上层。

应用层(系统应用 + 第三方应用) 应用框架层(ActivityManager、WindowManager等) 系统服务层(System Server、AMS、WMS、PMS等) 硬件抽象层HAL(Camera HAL、Audio HAL等) Linux内核层(驱动、进程管理、内存管理) Binder IPC

我的经验:学习架构不要死记硬背。我建议你从应用层写一个简单的App,然后逐步往下追踪。比如写一个"点击按钮弹出Toast"的功能,看看它最终调用了哪些系统服务。这样学,记得牢。

二、AOSP源码下载与编译环境搭建

理论讲完了,咱们来点实际的。AOSP(Android Open Source Project)是Android的源代码仓库。想深入Framework,必须自己下载编译。我记得第一次下载AOSP时,光同步代码就花了两天——网速慢、磁盘不够、Python版本不对,各种问题。

2.1 环境准备

先说硬件要求。别想着用8GB内存的笔记本编译Android——你会等到怀疑人生。我建议至少16GB内存,256GB可用磁盘空间,CPU核心数越多越好。

  • 操作系统:Ubuntu 18.04/20.04 LTS(64位),macOS也行但坑更多
  • 磁盘:至少250GB空闲空间(AOSP源码约60GB,编译产物约150GB)
  • 内存:16GB起步,32GB更佳
  • 网络:稳定的科学上网环境,你懂的

避坑指南:我曾经在Windows上用虚拟机编译,结果磁盘IO成了瓶颈,编译一次要8小时。后来换了物理机装Ubuntu,时间缩短到2小时。所以——能用物理机就别用虚拟机。

2.2 下载AOSP源码

下载AOSP主要用repo工具。repo是Google基于Git做的多仓库管理工具。Android有几百个Git仓库,用repo一条命令就能全部同步。

# 1. 安装repo
mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

# 2. 创建工作目录
mkdir aosp
cd aosp

# 3. 初始化repo(以android-13.0.0_r41为例)
repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r41

# 4. 同步源码(-j4表示4个并行任务,根据CPU核心数调整)
repo sync -j4 -c

这里有个细节:-c参数表示只下载当前分支的代码,不下载历史记录。能省不少空间和时间。我第一次同步时没加这个参数,多下了20GB的git历史。

2.3 编译环境搭建

源码下载完后,需要安装编译依赖。Android官方提供了一个脚本,一键安装所有依赖包。

# 安装依赖
sudo apt-get update
sudo apt-get install -y git-core gnupg flex bison build-essential \
    zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
    libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev \
    lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig

# 安装JDK(Android 13需要OpenJDK 11)
sudo apt-get install openjdk-11-jdk

嗯,这里要注意:不同Android版本对JDK版本要求不同。Android 10以下用OpenJDK 8,Android 11及以上用OpenJDK 11。我见过有人用JDK 17编译Android 12,结果编译到一半报错,白白浪费半天时间。

2.4 开始编译

环境准备好后,就可以编译了。编译前需要先设置环境变量,然后选择编译目标。

# 设置环境
source build/envsetup.sh

# 选择编译目标
lunch aosp_arm64-eng

# 开始编译(-j16表示16个并行任务)
make -j16

lunch命令的参数格式是设备名-编译类型。编译类型有三种:

  • eng:工程版,包含调试工具,适合开发
  • userdebug:用户调试版,有root权限,适合测试
  • user:用户版,无root权限,适合发布

我个人习惯用aosp_arm64-eng,因为包含了完整的调试符号和工具。第一次编译大概需要2-4小时,之后增量编译会快很多。

关键提醒:编译过程中如果报错,不要慌。90%的错误都是环境问题——缺少依赖包、Python版本不对、磁盘空间不足。仔细看错误日志,Google一下基本都能解决。

2.5 编译产物与运行

编译成功后,产物在out/target/product/目录下。你可以用模拟器运行编译好的系统:

# 启动模拟器
emulator

或者刷到真机上。不过刷机有风险,我建议先用模拟器调试。模拟器启动后,你会看到一个纯净的Android系统——没有Google服务,没有厂商定制,就是最原始的AOSP。

小技巧:编译时加上showcommands参数,可以看到每条编译命令的详细信息。对理解编译过程很有帮助:make -j16 showcommands

好了,这一章的内容就到这里。Android系统架构是Framework学习的基石,AOSP源码是你最好的老师。下一章我们会深入Binder机制——Android系统的"神经系统"。记得动手实践,光看不练是学不会的。


公众号:蓝海资料掘金营,微信deep3321