Android 整机系统开发到底要学什么?
很多人一听到 Android 开发,第一反应是 App 开发:Activity、Fragment、View、Jetpack、网络请求、数据库、性能优化。但如果进入的是整机系统开发,面对的问题会完全不同。
整机系统开发关注的不是“如何写一个 App”,而是“如何让一台 Android 设备作为一个完整系统稳定运行”。它要处理的是 Framework、Native Service、HAL、Vendor、Kernel、Modem、权限、安全、编译、系统服务、日志分析、版本差异、厂商定制、运营商需求,以及各种跨模块问题。
所以,Android 整机系统开发到底要学什么?它不是简单地多看几份源码,也不是把 Android 所有模块都背下来,而是要建立一套系统视角:知道一台设备从开机到应用运行,中间经过了哪些层;知道问题发生时,应该从哪个层级切入;知道不同模块之间如何通信、如何协作、如何被调试。
一、先建立整体分层:Android 不是一个单层系统
学习整机系统开发,第一步不是直接钻进某个源码文件,而是先建立 Android 的整体分层模型。
可以粗略理解为:
App 层负责用户可见的功能,比如短信、电话、设置、相机、蓝牙入口等。
Framework 层提供系统能力的统一抽象,比如 ActivityManager、PackageManager、TelephonyManager、ConnectivityManager、PowerManager 等。
System Server 是大量核心系统服务的运行容器。很多 Framework 层能力最终都落到 System Server 中的具体 Service。
Native Service 则承载更底层、更贴近系统资源的服务,例如 SurfaceFlinger、AudioFlinger、netd、vold、installd 等。
HAL 是 Android Framework 和厂商硬件实现之间的接口边界。Framework 不应该直接关心具体硬件怎么实现,而是通过 HAL 访问厂商能力。
Kernel 和 Driver 则负责进程调度、内存、文件系统、网络协议栈、设备驱动、中断、电源管理等底层能力。
整机系统开发最重要的能力之一,就是知道一个问题可能位于哪一层,而不是看到现象就直接猜结论。
比如“网络不可用”这个现象,可能是 App 没有权限,可能是 Framework 状态机异常,可能是 netd 配置问题,可能是 DNS 问题,可能是 modem 注册状态异常,也可能是运营商网络侧行为导致。系统开发不能只看表面现象,而要逐层建立证据链。
延伸阅读
- Platform architecture - Android Developers:先用它校准 Android 软件栈的官方分层。
- Architecture overview - AOSP:从 AOSP 视角继续展开 Binder、HAL、构建、分区等主题。
- AOSP 源码:frameworks/base、system/core、hardware/interfaces:把架构图落到真实目录时,可以先从这几个仓库开始。
二、必须理解进程、线程和 Binder
Android 系统不是一个单进程程序。系统里有大量进程:普通 App 进程、system_server、surfaceflinger、netd、vold、mediaserver、vendor 进程、hal 进程等。
这些进程之间需要通信,而 Android 最核心的跨进程通信机制就是 Binder。
如果不了解 Binder,很容易出现几个典型误解:
第一,把远程服务当成本地对象理解。
第二,把 handle 当成真实对象地址理解。
第三,以为 Framework 调用某个 Manager 方法,就一定是在当前进程完成全部逻辑。
第四,不清楚 ServiceManager、BpBinder、BBinder、BnInterface、binder_node、binder_ref 之间的关系。
整机系统开发并不要求一开始就把 Binder 驱动每一行代码都看懂,但至少要理解:
客户端拿到的是代理对象
服务端持有的是真实服务对象
ServiceManager 负责服务注册和查询
Binder Driver 负责跨进程通信和引用关系维护
很多系统问题本质上都是跨进程调用链问题。比如 App 调用 Framework API,Framework 通过 Binder 进入 system_server,system_server 再调用 native service 或 HAL,最后返回结果。任何一个节点异常,都可能表现为上层功能失败。
所以学习 Android 系统,Binder 是主干,不是细节。
延伸阅读
- Binder overview - AOSP:官方对 Binder client、proxy、node、transaction 的解释最直接。
- AIDL overview - AOSP:很多 Framework 和 HAL 接口都会落到 AIDL,适合顺着接口声明理解调用代码。
- AOSP 源码:kernel/common/drivers/android/binder.c:看完概念后,可以用它对照内核侧对象、引用和事务维护方式。
三、必须理解 Handler、Looper 和系统线程模型
Android Framework 大量逻辑运行在消息循环之上。应用主线程有 Looper,system_server 中很多系统服务也有自己的 HandlerThread。
理解 Handler 不是为了背 API,而是为了理解系统如何“排队处理事情”。
一个系统服务经常会面对多种事件来源:
Binder 调用
广播
定时任务
底层回调
状态机事件
配置变化
用户操作
这些事件不可能全部在同一个调用栈里立即完成。很多时候,系统会把事件封装成 Message,投递到某个 Handler,由对应线程串行处理。
这就引出了几个重要问题:
某个逻辑到底在哪个线程执行?
为什么不能在 Binder 线程里做耗时操作?
为什么有些状态不是马上变化,而是异步更新?
为什么 log 看起来顺序不符合直觉?
为什么某个回调触发了,但最终状态没有变化?
如果不理解 Handler 和 Looper,很容易只看到函数调用,而看不到真正的执行时序。整机系统开发里,时序问题、异步问题、状态机问题非常常见,这些都离不开线程和消息机制。
延伸阅读
- Looper - Android Developers API Reference:先确认线程、
prepare()和loop()的官方语义。 - Handler - Android Developers API Reference:再看 Handler 如何把 Message、Runnable 和线程队列绑定起来。
- AOSP 源码:Looper.java、Handler.java、MessageQueue.java:源码适合核对消息入队、取队、分发和同步屏障这些细节。
四、必须理解 System Server 和核心系统服务
System Server 是 Android 系统中非常核心的进程。很多 Framework 能力都由 system_server 中的系统服务提供。
常见服务包括:
ActivityManagerService
PackageManagerService
WindowManagerService
PowerManagerService
DisplayManagerService
ConnectivityService
TelephonyRegistry
NotificationManagerService
InputManagerService
学习这些服务时,不建议一开始就平铺式阅读源码。更好的方式是从问题入口进入。
比如:
应用为什么能启动?
权限是在哪里检查的?
应用安装后 Package 信息如何被系统识别?
网络状态变化如何通知到应用?
亮灭屏状态如何传递?
输入事件如何分发?
电话状态如何广播给上层?
每个问题都可以牵出一条系统链路。链路看多了,System Server 的结构自然会变清晰。
整机系统开发者不一定要成为每个服务的专家,但要知道核心服务分别负责什么,遇到问题时应该先查哪个服务、哪个 log、哪个 dumpsys。
延伸阅读
- AOSP 源码:SystemServer.java:理解 system_server,第一站就是它的启动流程和服务分组。
- AOSP 源码:ActivityManagerService.java:AMS 适合拿来练习应用生命周期、进程管理和系统调度链路。
- Application fundamentals - Android Developers:从应用组件入口反推系统服务为什么要管理 Activity、Service、广播和 Provider。
五、必须理解 Native Service 和 HAL 边界
Android 并不是全部由 Java 实现。越靠近系统资源和硬件,C++ 与 Native 层越重要。
例如:
SurfaceFlinger 负责图形合成。
AudioFlinger 负责音频相关处理。
netd 负责网络配置相关能力。
vold 负责存储卷管理。
installd 负责应用安装相关的底层操作。
这些服务通常通过 Binder、Socket、HIDL、AIDL HAL 等机制与上层或厂商实现通信。
学习 Native Service 的关键是理解“边界”:
Framework 到底负责什么?
Native Service 到底负责什么?
HAL 到底负责什么?
Vendor 实现到底负责什么?
Kernel Driver 到底负责什么?
整机系统开发中,很多争议都发生在边界处。一个问题到底归 Framework、Vendor、Modem、Kernel、网络侧还是 App?这不能靠感觉判断,而要靠调用链、状态机、日志和对系统边界的理解。
延伸阅读
- Hardware abstraction layer overview - AOSP:先把 HAL client、HAL interface、HAL service 这些术语对齐。
- AIDL for HALs - AOSP:新版本 Android 越来越强调稳定 AIDL HAL,这里适合看接口演进方向。
- AOSP 源码:hardware/interfaces、SurfaceFlinger、AudioFlinger:从标准接口和典型 native service 两头看,更容易判断边界。
六、必须补 Linux 基础
Android 是建立在 Linux Kernel 之上的系统。做整机系统开发,如果完全不懂 Linux,很容易卡在底层问题上。
需要掌握的 Linux 基础包括:
进程、线程、调度、内存、文件描述符、Socket、epoll、权限、SELinux、日志、设备节点、文件系统、网络协议栈、驱动基本概念。
这些知识不一定要一开始学到内核专家级别,但至少要能理解:
进程为什么会卡住?
线程为什么会死锁?
fd 泄漏是什么?
socket 通信如何定位?
epoll 为什么常见于 native service?
SELinux denied 为什么会导致功能失败?
设备节点权限为什么会影响 HAL?
系统资源不足为什么会造成随机异常?
Android 的很多问题表面在 Framework,根因却可能在 Linux 层。没有 Linux 基础,就很难把问题查到底。
延伸阅读
- Kernel overview - AOSP:官方解释了 Android Kernel、LTS 和 Android Common Kernels 的关系。
- Security-Enhanced Linux in Android - AOSP:遇到
avc: denied之前,最好先把 domain、context、policy 的概念补齐。 - AOSP 源码:system/sepolicy:定位 SELinux 问题时,最终经常要把日志和策略文件对上。
七、必须掌握系统调试工具
整机系统开发不是只看代码,更重要的是会定位真实设备问题。
常用工具包括:
logcat
dmesg
bugreport
dumpsys
dumpsys activity
dumpsys package
dumpsys window
dumpsys power
dumpsys connectivity
dumpsys telephony.registry
ps / top
ss / netstat
getprop / setprop
cmd
service call
atrace / systrace / perfetto
tombstone
ANR traces
真正的调试能力不是知道这些命令的名字,而是知道什么时候用什么。
比如:
应用行为异常,先看 logcat 和 dumpsys activity。
网络状态异常,要看 ConnectivityService、netd、ip rule、路由、DNS、modem 状态。
系统卡顿,要看 trace、CPU、锁等待、主线程阻塞。
Native crash,要看 tombstone。
权限问题,要看 App 权限、系统权限、SELinux、UID、进程上下文。
服务不存在,要看 ServiceManager、init、进程是否启动、rc 配置、权限和崩溃记录。
整机系统开发的调试目标不是“找到一条可疑 log”,而是把现象、时间点、调用链、状态变化和责任边界串起来。
延伸阅读
- Read bug reports - AOSP:读 bugreport 时,可以用它先熟悉 logcat、dumpsys、dumpstate 的结构。
- Debug native Android platform code - AOSP:native crash、tombstone、debuggerd 这些平台级调试入口都可以从这里展开。
- perfetto - Android Developers:当单条日志解释不了卡顿、调度和跨线程时序时,Perfetto 更有用。
八、必须理解编译、分区和版本
整机开发离不开版本管理和系统构建。
需要理解:
Android 编译系统如何组织模块?
system、vendor、product、odm、system_ext 分区分别放什么?
为什么同一个功能在不同项目、不同 Android 版本上表现不同?
GSI、VTS、CTS、兼容性要求意味着什么?
系统属性 property 如何影响功能开关?
overlay 和配置文件如何改变系统行为?
一套 Android 代码落到不同项目上,往往会有大量厂商定制和项目差异。如果不理解编译和分区,就容易出现“源码里明明是这样,设备上却不是这样”的困惑。
整机系统开发必须同时看源码和实际镜像,不能只相信代码仓库里的静态内容。
延伸阅读
- Build overview - AOSP:Soong、Kati、Ninja、Android.bp 这些构建基础,可以先从官方说明入手。
- Partitions overview - AOSP:理解 system、vendor、product 等分区后,很多“源码和设备表现不一致”的问题会清楚很多。
- Android Compatibility Definition Document - AOSP:整机功能不是跑通就结束,CDD 是兼容性要求的重要依据。
- Generic system images - AOSP:GSI 和 VTS/CTS 的关系,适合用来理解平台通用镜像如何验证 vendor 接口。
九、学习路线应该是 T 型结构
Android 整机系统太大,不可能一开始全部精通。更合理的方式是建立 T 型能力。
横向要知道系统分层和主要模块:
Framework
System Server
Binder
Handler
Native Service
HAL
Kernel
SELinux
Build
Debug Tools
纵向要选择一两个方向深入,比如:
Telephony
Connectivity
Audio
Display
Camera
Power
Package / Permission
Input
Storage
如果只横向了解,会变成“什么都知道一点,但无法解决深问题”。
如果只纵向钻一个模块,又容易被单一业务困住,看不到系统全局。
比较理想的状态是:
有一条自己熟悉的业务主线,同时不断把这条主线向上下游扩展。
例如做网络问题,就不能只看 Settings 里的开关,也要理解 ConnectivityService、NetworkAgent、netd、DNS、路由、iptables、modem 状态、运营商配置等。
例如做电话短信问题,就不能只看上层 UI,也要理解 Telephony Framework、RIL、IMS、Subscription、CarrierConfig、广播通知、数据库和权限。
延伸阅读
- Get started with Android development - AOSP:把源码下载、构建、测试这些基本动作串起来,适合作为整机学习入口。
- Download the Android source - AOSP:真正做系统学习,迟早要把 repo、分支和源码树工作流跑通。
- Android Code Search:横向查符号、纵向追调用链,都离不开一个顺手的源码检索入口。
十、最终要形成的是“问题定位模型”
Android 整机系统开发的核心能力,不是背源码,而是建立问题定位模型。
一个成熟的定位过程通常包括:
1. 明确现象:用户到底看到什么?
2. 确认范围:必现还是偶现?单项目还是多项目?单版本还是多版本?
3. 锁定时间点:异常发生在什么时候?
4. 建立链路:从上层入口到下层实现经过哪些模块?
5. 查状态:每一层当时的状态是否符合预期?
6. 查调用:关键调用有没有发生?返回值是什么?
7. 查边界:问题属于 App、Framework、Native、HAL、Kernel、Vendor、Modem 还是网络侧?
8. 给结论:结论必须由证据支撑,而不是猜测。
这也是整机系统开发和普通功能开发最大的区别之一。
普通功能开发更关注“如何实现”。
整机系统开发更关注“系统为什么表现成这样”。
延伸阅读
- Read bug reports - AOSP:问题定位最终要落到证据,bugreport 是训练证据链的好材料。
- Android Debug Bridge - Android Developers:adb 是连接真实设备和定位命令的基础工具。
- Overview of system tracing - Android Developers:复杂时序问题要看线程调度、等待和执行区间,trace 比日志更直观。
- AOSP 源码:frameworks/native/cmds/dumpsys:想把 dumpsys 从“命令”还原成 Binder 服务访问,可以看这个入口。
结语:Android 整机系统开发学的是系统思维
Android 整机系统开发要学的东西很多,但可以总结成一句话:
它学的不是某一个 API,也不是某一个模块,而是如何理解一台 Android 设备作为完整系统运行的方式。
要学 Framework,因为它定义了系统能力的上层抽象。
要学 Binder,因为它连接了不同进程和服务。
要学 Handler,因为它解释了大量异步时序问题。
要学 System Server,因为核心系统服务大多运行在这里。
要学 Native Service 和 HAL,因为很多真实能力最终会落到系统底层和厂商实现。
要学 Linux,因为 Android 的根基仍然是操作系统。
要学调试工具,因为真实问题不会按照教程出现。
要学编译和分区,因为设备上的系统不是单一源码文件,而是一套复杂的工程产物。
最终,整机系统开发者要建立的是一种能力:面对一个复杂问题,能够从现象出发,沿着系统分层逐步拆解,找到证据,明确边界,给出可靠结论。
这就是 Android 整机系统开发真正要学的东西。
延伸阅读
- AOSP Docs:后续继续扩展时,优先回到官方文档,而不是先找零散文章。
- Android Code Search:系统思维最终要能被源码验证,Code Search 适合持续追踪调用链和版本差异。