前言(Preface)¶
Android 的增长堪称现象级。在极短的时间里,它就成功跻身市场上最主流的移动平台之列。开源许可、激进的市场推进策略,以及符合潮流的界面体验,这三者的组合显然正在为 Google 的 Android 团队带来回报。
不用说,Android 带来的海量用户增长,也让手机厂商、移动运营商、芯片厂商、应用开发者纷纷侧目。各种“面向 Android”“兼容 Android”“基于 Android”的产品与设备,几乎以肉眼可见的速度涌现出来。
但除了在手机领域的成功之外,Android 也吸引了另一群原本并非目标用户的关注:嵌入式系统开发者。许多嵌入式设备几乎没有人机交互界面,但也有相当一部分传统意义上的“嵌入式设备”拥有 UI。对越来越多面向用户的设备而言,开发者除了实现技术功能,还必须面对人机交互(HCI)问题:要么让用户获得一种他们已经习惯的体验,要么就必须自己从零构建一套复杂的交互系统。
这也正是 Android 在嵌入式领域的机会所在:它提供了一套成熟的应用框架、图形栈和交互体系。
然而,想在嵌入式设备中使用 Android 也并不容易。虽然社区里有大量零散的博客、在线文档,也确实有一些书籍(例如 O’Reilly 的《Learning Android》),但嵌入式开发者真正能依赖的,往往只剩下 Google 在 https://source.android.com 提供的那套“极简文档”。于是,认真考虑在系统里引入 Android 的嵌入式开发者,很多时候只能从 Android 源码本身开始啃。
本书的目的,就是改善这一现状:帮助你把 Android 嵌入到任何设备中。因此,你将学习 Android 的整体架构、如何在源码树中定位与理解各模块、如何修改关键组件、以及如何为你的特定设备构建属于你自己的 Android 版本。
除此之外,你还将了解 Android 如何与 Linux 内核集成,并理解它与 Linux “血统”之间的共性与差异。例如,我们会讨论 Android 如何利用 Linux 的驱动模型来构建自己的硬件抽象层(HAL),以及如何把 glibc、BusyBox 等“传统/遗留”的 Linux 组件打包进 Android 体系。
在这个过程中,你也会学到许多实战技巧:比如如何使用 Android 的 repo 工具、如何集成或修改 Android 的编译系统等。
我第一次接触 Android 时,把它当作一本“说明书”一样认真阅读:我通读了大部分内容,划出了很多我认为关键的段落,在页边写下了大量笔记,并列出了一长串“找不到答案的问题”。与此同时,我也开始探索 Android Open Source Project(AOSP)公开的源代码。坦白讲,我大概花了 6 到 12 个月,才逐渐有信心在 AOSP 里自由穿梭。
你现在读到的这本书,是我自开始研究 Android 以来的工作沉淀——包括我参与的多个项目:帮助不同团队将 Android 定制到他们的嵌入式产品中。
不过,我也需要强调:本书并不试图面面俱到。Android 及其内部机制中还有大量内容,本书无法覆盖,也不可能覆盖完整。但它应该能帮助你快速起步,让你更高效地把 Android “塑形”为符合你需求的系统。
本书面向谁¶
本书主要面向:
- 计划基于 Android 构建嵌入式系统的开发者
- 或者希望将 Android 定制到特定用途场景的开发者
默认你已经具备嵌入式/系统开发的基础能力(尤其是 Linux 相关知识)。
内容组织¶
与许多技术书一样,本书的章节会逐步增加复杂度:前几章为后续内容打基础。若你是管理者,只想抓住核心要点;或你希望知道读完哪些章节后就可以“按需跳读”,我建议你至少读完前三章。并不是说后面的章节不重要,而是从那之后内容的模块化程度会显著提高。
- 第 1 章《引言》:介绍嵌入式场景使用 Android 需要了解的基础信息,例如 Android 的来历、它的开发模式与许可协议与传统开源项目的不同,以及运行 Android 所需的硬件要求。
- 第 2 章《内部入门》:深入 Android 内部,介绍其核心抽象。先从应用开发者熟悉的模型入手,然后讨论 Android 对内核的修改、硬件支持方式、原生用户空间、Dalvik、System Server,以及整体系统的启动流程。
- 第 3 章《AOSP 初探》:带你开始“动手”。包括如何获取 AOSP、理解源码树结构、进行编译与运行、以及使用常用工具(如 ADB、模拟器等)。
- 第 4 章《编译系统》:讲解 Android 编译系统的架构、配置方式和常见用法,并给出多种实用技巧。
- 第 5 章《硬件入门》:介绍 Android 设备常见硬件形态与典型 SoC 架构,帮助你理解 Android 为什么会在硬件上做出某些设计选择。
- 第 6 章《原生用户空间》:从文件系统布局、init/ueventd、常用原生命令与守护进程等角度,系统梳理 Android 的原生用户空间。
- 第 7 章《Android 框架层》:聚焦 Framework、系统服务、启动过程、HAL 等核心机制,帮助你理解“框架层到底在做什么”。
附录部分:
- 附录 A《遗留用户空间》:介绍如何把“传统 Linux 用户空间”组件带入 Android 世界。
- 附录 B《为新硬件添加支持》:演示如何扩展 Android 栈以支持新硬件(包括新增系统服务、扩展 HAL 等)。
- 附录 C《自定义默认包列表》:给出如何调整 AOSP 默认包含内容的指导。
- 附录 D《默认 init.rc 文件》:提供 2.3/Gingerbread 与 4.2/Jelly Bean 的默认 init.rc 文件(带注释)。
- 附录 E《资源》:列出你可能用得上的网站、邮件列表、书籍与活动。
软件版本说明¶
当你拿起这本书时,可能就已经猜到:本书覆盖的 Android 版本很可能落后于当前最新版本,而且这种情况未来大概率也会一直存在。
原因很简单:Android 大约每 6 个月发布一次新版本,而写一本书往往需要更长的周期。作者完成本书耗时近两年;而即使要更新一个版本,往往也需要 6 个月到 1 年甚至更久。
因此,本书更希望帮助你建立“理解 Android 的方法论”与“定位问题的思路”,而不是仅仅做一本追版本号的手册。
本书排版约定¶
本书使用以下排版约定:
- 斜体:表示新术语、URL、邮箱地址、文件名、文件扩展名等。
等宽字体:用于代码清单;或在段落中引用程序元素,如变量名、函数名、数据库、数据类型、环境变量、语句、关键字等。等宽加粗:表示需要用户原样输入的命令或文本。等宽斜体:表示需要被用户输入值替换的占位内容,或根据上下文决定的值。
提示:表示建议、技巧或一般性说明。
警告:表示需要特别注意的风险或陷阱。
使用示例代码¶
本书的目标是帮助你把工作做成。
一般来说,你可以在你的程序与文档中使用本书中的代码示例。除非你要复制本书中相当大比例的代码到你的产品文档里,那通常需要获得许可。
我们欢迎(但不强制要求)署名。通常署名会包括书名、作者、出版社与 ISBN。例如:
“Embedded Android by Karim Yaghmour(O’Reilly). Copyright 2013 Karim Yaghmour, 978-1-449-30829-2.”
如果你认为你对代码示例的使用超出了合理使用范围,或超出了上面的许可,请联系:permissions@oreilly.com。
Safari® Books Online¶
Safari Books Online 是一个按需数字图书馆,你可以在其中检索大量技术与创意类参考书籍与视频,以更快找到答案。
通过订阅,你可以在线阅读任意页面、观看任意视频;也可以在手机与移动设备上阅读。你还能在纸质版出版之前访问新书,并对仍在编写中的稿件提出反馈。
更多信息请访问:https://www.oreilly.com。
致谢¶
这是我写的第二本书,也是我十年来写的第一本。
写这种类型的书,必须极度谨慎以确保技术准确性。因此,拥有一支强大的技术审校团队对我至关重要。首先我要感谢 Magnus Bäck、Mark Gross 和 Amit Pundir,他们在项目早期就同意审阅本书,并在漫长的写作周期里提供了大量反馈。
随着项目推进,更多优秀的人加入:硬件专家 David Anders 对硬件章节提供了关键反馈;Robert PJ Day 帮助确保内容对从未接触 Android 的读者也易于理解;Benjamin Zores 细致梳理了栈内部的多个问题。还有一些早期版本的读者(如 Andrew Van Uitert 与 Maxime Ripard)也友善地指出了他们发现的问题。
我尤其要感谢 Linaro 的 Android 团队,特别是 Bernhard Rosenkränzer——他们几乎以一己之力指出了早期版本(当时更偏 Android 2.3/Gingerbread)与 Android 4.2/Jelly Bean 之间的大量差异。
此外,尽管 Android 的开发是一个透明度并不高(出于各种原因也可以理解)的开源项目,我仍要感谢那些以不同方式提供帮助(或者至少尝试过帮助)的 Android 开发者。感谢 Brian Swetland 在 LWN 上不时补上关键“空白”,也感谢 Chet Haase。
最后,这份致谢必须献给我最亲近的人:Sonia、Anaïs、Thomas 与 Vincent。感谢你们在整个写作过程中给予的爱与耐心。
注:原文末尾含一句法语致谢,大意为“写在字里行间的那些无形之手属于他们,我对此深怀感激”。