Post

如何用模拟器调试Android Framework

如何用模拟器调试Android Framework

近期在看Android上的某个新特性,需要自行搭建环境编译镜像,记录下折腾过程。

在Android模拟器上调试apk是很方便的,调试Framework就没那么方便了。本文介绍如何在模拟器上调试Framework。由于手头资源受限,我的调试环境如下:

  • Ubuntu 20.04上下载AOSP源码,交叉编译arm64镜像
  • Mac M4 Pro上运行模拟器加载自行编译的镜像

1. 下载AOSP源码

下载编译Android源码的Host机器,需满足以下条件:

  • Ubuntu 20.04及以上
  • 可用磁盘空间300GB以上(我就是被这一条卡住了,否则直接本机编译本机运行会方便很多)
  • 能翻墙从Google官网下载,如果不能,需使用国内镜像

下载AOSP代码,这里指定了具体的分支android-16.0.0_r4

1
2
repo init -u https://android.googlesource.com/platform/manifest -b android-16.0.0_r4
repo sync -c --no-tags --no-clone-bundle

接下来是漫长等待,估计要大半天才能下载好。一方面看你的网络好不好,另一方面是Google或者其他镜像站点都有限流机制。

2. 编译

注意lunch的参数:

  • sdk_phone64_arm64:product的名字,我编译的是arm64的,list_products可查看所有支持的product
  • userdebug:版本类型,list_variants可查看所有类型
  • bp4a:版本代号,list_releases可查看全部的,从Android版本信息可以查到bp4a对应android-16.0.0_r4
    1
    2
    3
    
    source build/make/envsetup.sh
    lunch sdk_phone64_arm64-bp4a-userdebug
    m -j64
    

接下来又是漫长的等待,看个人机器性能。我的机器由于是机械硬盘,io不行,这一步又是大半天。

3. 打包镜像

由于要在别的机器上使用这个镜像,按照官方文档的说明打包:

1
make emu_img_zip

这个过程还是比较快的,成功后,会生成下面的压缩包:

1
out/target/product/emu64a/sdk-repo-linux-system-images.zip

4. 创建模拟器

官方给的共享方案是在Android Studio的SDK Manager中添加SDK Update Sites,需要将sdk-repo-linux-system-images.zip和repo-sys-img.xml托管为http服务。问题是现在没有命令可以生成repo-sys-img.xml了,需要自己找模版手写!!!

我没有用这种方法,直接狸猫换太子:先在Android Studio中创建对应版本的模拟器(创建过程中根据提示下载官网镜像),然后在模拟器详情页面找到镜像存储路径,用自己的镜像替换。 如下图所示,镜像路径是相对目录system-images/android-36.1/google_apis/arm64-v8a, MacOS上全路径是~/Library/Android/sdk/system-images/android-36.1/google_apis/arm64-v8a

镜像路径

替换后,启动模拟器,通过下面的命令查看编译时间,确认是否替换成功:

1
adb shell getprop ro.vendor_dlkm.build.date

这个过程还是有点麻烦的。后续每次修改,都要这样搞吗?
如果改动不涉及对外接口,大部分情况是可以局部替换的,下面介绍我经常使用的两种场景。

5. framework.jar如何替换

比如修改了frameworks/base/core/java/android/app/Activity.java,首先重编它所属的模块:

1
make -j64 framework-minus-apex

生成的产物是out/target/product/emu64a/system/framework/framework.jar。 先根据Android模拟器如何remount把模拟器remount,然后push到设备:

1
adb push framework.jar /system/framework/

保险起见,删除AOT预编译产物:

1
2
rm -rf /system/framework/arm
rm -rf /system/framework/arm64

然后重启system_server,或者重启设备:

1
killall system_server

6. 二进制so如何替换

比如修改了system/core/libutils/Looper.cpp, 首先编译:

1
m -j64 libutils

产物是out/target/product/emu64a/system/lib64/libutils.so

remount设备后直接push,然后重启设备即可:

1
adb push libutils.so /system/lib64/

7. 参考文档

  • https://source.android.com/docs/setup/test/avd
  • https://developer.android.com/studio/intro/update#adding-sites
  • https://tech.coderhuo.tech/posts/remount_android
This post is licensed under CC BY 4.0 by the author.

© coderhuo. Some rights reserved.

本站总访问量次,本文总阅读量

Using the Chirpy theme for Jekyll.