4. 开发环境搭建
要开发 Android System Service,第一步不是写代码,而是把“能编译、能跳转、能调试”的闭环搭起来。系统服务位于 frameworks/base/services 等目录,依赖 AOSP 全量源码、Soong/Ninja 构建系统以及平台签名,因此环境搭建的质量直接决定后续开发效率。本节围绕源码下载、编译环境配置、Android Studio 与系统源码配合三条主线展开。
一、核心原理:系统服务开发环境的三层结构
系统服务开发环境可以理解为三层:源码层、构建层、IDE 层。源码层提供 frameworks、system、packages 等完整代码;构建层由 repo、Soong、Ninja、Jack/Java 工具链组成,负责把 Java/Kotlin/C++ 代码编译成 system.img、framework.jar;IDE 层则通过 Android Studio 索引源码,实现跳转、补全与断点调试。三者缺一不可,只下载源码不配置 IDE,阅读效率极低;只配置 IDE 不编译,无法验证服务是否真正生效。
二、AOSP 源码下载:repo 与分支选择
AOSP 使用 repo 管理数百个 Git 仓库。下载前需安装 repo、配置 Git 用户信息,并选择与目标设备匹配的分支。以 Android 14 为例,常用标签为 android-14.0.0_r1。下载命令如下:
# 安装 repo
mkdir ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH
# 初始化并同步
mkdir aosp && cd aosp
repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r1
repo sync -c -j8 --no-tags --force-sync
若网络受限,可使用清华、中科大等镜像源替换 manifest 地址。同步完成后,源码体积通常在 100GB 以上,建议预留 250GB 以上磁盘空间,并使用 ext4 或 APFS 文件系统,避免大小写敏感问题。
三、编译环境配置:依赖、JDK 与构建命令
编译 AOSP 需要 Linux 环境(推荐 Ubuntu 20.04/22.04),并安装大量依赖包。核心依赖包括 git、curl、python3、openjdk-11-jdk、bison、flex、libssl-dev 等。安装完成后,通过 envsetup.sh 初始化构建环境:
sudo apt install -y git curl python3 openjdk-11-jdk \
bison flex libssl-dev libxml2-utils zip unzip
source build/envsetup.sh
lunch aosp_arm64-userdebug
m -j$(nproc)
其中 lunch 选择目标产品与构建变体,userdebug 适合系统服务开发,因为它保留 root 与调试能力。首次全量编译可能耗时 1~3 小时,增量编译则只需数分钟。编译产物位于 out/target/product/<device>/ 下,system.img、framework.jar 是后续刷机与调试的关键文件。
四、Android Studio 与系统源码配合使用
Android Studio 默认无法直接索引 AOSP 全量源码,需要借助 idegen 生成项目文件。在 AOSP 根目录执行:
source build/envsetup.sh
lunch aosp_arm64-userdebug
mmm development/tools/idegen
development/tools/idegen/idegen.sh
执行完成后会生成 android.ipr 与 android.iml。用 Android Studio 打开 android.ipr,即可获得跨模块跳转、类继承关系查看与断点调试能力。若索引过慢,可在 android.iml 中排除 out、prebuilts、external 等非必要目录,只保留 frameworks、system、packages 等核心路径。
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| 操作系统 | Ubuntu 22.04 LTS | 官方支持最好,依赖安装方便 |
| JDK | OpenJDK 11 | Android 13+ 编译要求 |
| 磁盘 | ≥ 250GB SSD | 源码 + out 目录占用大 |
| 内存 | ≥ 32GB | Ninja 并行编译需要 |
| 构建变体 | userdebug | 保留 root 与调试能力 |
| IDE 项目文件 | android.ipr | 由 idegen 生成 |
五、案例与误区复盘
一个典型场景是:开发者修改了 frameworks/base/services/core/java/com/android/server/<YourService>.java,希望验证服务是否随系统启动。正确流程是:mmm frameworks/base/services 编译模块,adb sync 或刷入 system.img,重启设备后通过 adb logcat | grep YourService 查看日志。若只执行 m 而未 lunch,会出现“无法找到目标”的错误;若未 source envsetup.sh,mmm 命令不可用。
环境搭建完成后,建议做一次“最小验证”:新建一个继承 SystemService 的类,注册到 SystemServer,编译并刷机,确认 logcat 输出。这个闭环一旦跑通,后续所有系统服务开发都将建立在此基础之上。