3、系统服务开发环境搭建:IDE配置、源码索引、调试工具准备
说实话,很多刚接触AOSP的朋友,第一步就栽在环境搭建上。
不是IDE卡死,就是源码索引半天出不来,更别提调试了。我当年第一次搭AOSP开发环境,光等源码编译就等了整整一个通宵,结果第二天发现JDK版本不对,又重来一遍……嗯,这些坑咱们今天一次性填平。
3.1 IDE选择与配置:别在编辑器上纠结
我个人习惯用IntelliJ IDEA,社区版就够用。为什么不用Eclipse?说白了,AOSP的源码结构太庞大了,Eclipse的索引引擎扛不住。你想想看,几万个Java文件同时加载,IDE直接卡成PPT。
我建议你直接上IntelliJ IDEA 2023.2以上版本,对AOSP的支持更友好。具体配置步骤如下:
- 安装JDK:必须用OpenJDK 11或17,Oracle JDK在AOSP里会有兼容性问题。我在项目中遇到过因为JDK版本不对,导致编译出来的系统服务在真机上跑不起来的情况。
- 导入源码:不要直接Open整个AOSP目录,那样IDE会崩溃。正确做法是只导入
frameworks/base和packages/services这两个核心模块。 - 调整内存:在
idea64.exe.vmoptions里把-Xms设为2048m,-Xmx设为8192m。别心疼内存,AOSP源码就是吃内存大户。
小技巧:在导入源码前,先执行
source build/envsetup.sh && lunch 生成 out/soong/.bootstrap 目录,这样IDE能识别AOSP的模块依赖关系。
3.2 源码索引:让IDE认识AOSP
源码索引是环境搭建里最磨人的一步。我记得第一次索引AOSP,等了快两个小时,结果中途断电……那种绝望感,懂的都懂。
这里我分享一个加速索引的方法:
- 排除无用目录:在IDE里右键Mark Directory as Excluded,把
out/、prebuilts/、external/这些目录排除掉。这些目录占了源码体积的60%以上,但对我们写系统服务来说基本用不上。 - 使用模块化索引:只索引你当前开发的模块。比如你写系统服务,就只索引
frameworks/base/services和frameworks/base/core。其他模块等需要时再手动添加。 - 开启省电模式:索引期间把笔记本插上电源,关闭其他应用。我见过有人开着Chrome的50个标签页跑索引,结果IDE直接OOM崩溃。
注意:索引完成后,第一次打开某个Java文件可能会很慢,因为IDE在构建符号表。别急,等个一两分钟就好了。千万不要中途强制关闭IDE,否则索引会损坏,又得重来。
3.3 调试工具准备:三板斧
调试系统服务,光靠Logcat是不够的。你需要三样东西:
| 工具 | 用途 | 我的经验 |
|---|---|---|
| adb logcat | 查看运行时日志 | 配合 logcat -b events 看系统事件,比看普通日志更高效 |
| gdb/lldb | 调试Native代码 | 系统服务里如果用了JNI,必须用这个。我曾经用gdb定位过一个内存泄漏,花了三天 |
| Android Studio Profiler | 性能分析 | 看CPU、内存、网络,比你自己加时间戳靠谱一百倍 |
具体怎么配?我建议你这样做:
- Logcat配置:在
~/.bashrc里加个别名alias al='adb logcat -v threadtime',这样每次敲al就能看到带线程和时间的日志,排查问题快很多。 - gdb配置:AOSP自带了一个
development/scripts/gdbclient.py脚本,直接source它就能连上模拟器或真机。别自己手写gdb命令,太容易出错了。 - Profiler连接:用Android Studio的Profiler时,记得先
adb root再adb remount,否则有些系统进程的权限不够,看不到完整数据。
避坑指南:我曾经在调试一个系统服务时,发现Logcat里死活看不到我的日志。折腾了半天,才发现是 android:debuggable 没设为 true。记住,系统服务默认是不输出调试日志的,你需要在AndroidManifest里显式开启。
3.4 实战:验证环境是否搭好
环境搭没搭好,跑个简单的例子就知道了。我建议你写一个最小的系统服务,打印一行日志:
// 在 frameworks/base/services/core/java/com/android/server/ 下新建一个 TestService.java
public class TestService extends SystemService {
public TestService(Context context) {
super(context);
}
@Override
public void onStart() {
Slog.i("TestService", "环境搭建成功!");
}
}
然后编译、刷机、看Logcat。如果能看到这行日志,恭喜你,环境搭好了。如果看不到……嗯,回头检查一下前三步,大概率是索引没配好或者JDK版本不对。
好了,环境搭建就这些。下一章咱们开始写第一个真正的系统服务,到时候你会感谢今天把环境搭得这么稳的自己。