快速调试安卓Framework源码二(导入单个java文件即可进行编译)
---------------------------------------------------------------------------------------------
0. 序
在Q上使用 mm 编译 quickbuild 很快, 在 R 上却很慢, 于是改变了一点实现方式。新的方式在 R 上也可以很快。【S 版本上这个方法还不行】
先看效果:

7s 左右就可以完成编译。 (ninja 前面的 time 是为了计算命令执行的时间,当我们工作编译的时候可以不添加)
好处:除了快,还可以跨机型。比如:可以使用 J1S 开发版的代码 push 到 K2 的稳定版 ROM 的机器上。这是因为我们单独编译的这个 .java 文件在 J1S 开发板和 K2 稳定版上可能是一样的(尽管这个 .java 之外的其他代码不一样)。即使不一样,我们对比一下两者代码,通过重载方法的方式,API兼容两者,可以做到在 K2 稳定版上面使用。
1. 创建目录结构
在项目工程创建目录结构如下
$tree frameworks/base/services/tests/mini_framework` `frameworks/base/services/tests/mini_framework``├── Android.bp``└── com`` ``└── android`` ``├── internal`` ``│ └── BrightnessSynchronizer.java ``// framework.jar 中的代码`` ``└── server`` ``└── display`` ``├── DisplayPowerControllerInjector.java ``// miui/frameworks/base 中 service 的代码,只要保证目录结构和包名对应即可`` ``└── DisplayPowerController.java ``// services.jar 中的代码
其中 Android.bp 内容如下:
//########################################################################``// MIUI mini framework project.``//########################################################################` `java_library {`` ``name: ``"miui_services0"``,`` ``srcs: [`` ``"com/android/server/display/DisplayPowerController.java"``,`` ``// 自己修改过的某个 .java 文件, 是 services.jar 中的代码,`` ``// 之前目录为: frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java`` ``"com/android/server/display/DisplayPowerControllerInjector.java"``,`` ``],`` ``libs: [ ``// 依赖 lib`` ``"services.accessibility"``,`` ``"services.appwidget"``,`` ``"services.autofill"``,`` ``"services.backup"``,`` ``"services.core"``,`` ``"services.devicepolicy"``,`` ``"services.net"``,`` ``"services.people"``,`` ``"services.usage"``,`` ``],`` ``installable: ``true``,``}` `java_library {`` ``name: ``"miui_framework0"``,`` ``srcs: [`` ``"com/android/internal/BrightnessSynchronizer.java"``,`` ``// 自己修改过的某个 .java 文件, 是 framework.jar 中的代码,`` ``// 之前目录为: frameworks/base/core/java/com/android/internal/BrightnessSynchronizer.java`` ``],`` ``libs: [`` ``"services.accessibility"``,`` ``"services.appwidget"``,`` ``"services.autofill"``,`` ``"services.backup"``,`` ``"services.core"``,`` ``"services.devicepolicy"``,`` ``"services.net"``,`` ``"services.people"``,`` ``"services.usage"``,`` ``"unsupportedappusage"``,`` ``],`` ``installable: ``true``,``}
2. 编译
先使用 make 命令编译一下 framework.jar 和 services.jar
make framework-minus-apex -j8
make services -j8
再使用 make 命令编译一下 miui_framework0.jar 和 miui_services0.jar
make miui_framework0 -j8
make miui_services0 -j8
这时候我们把需要修改 .java 文件进行修改,再使用 ninja 编译就很快。
ninja miui_framework0 (或者 prebuilts/build-tools/linux-x86/bin/ninja miui_framework0)
ninja miui_services0 (或者 prebuilts/build-tools/linux-x86/bin/ninja miui_services0)
非常的 Amazing!
这时候发现无论是修改 miui_services0.jar 还是 miui_framework0.jar 中的代码都是短短几秒就完成了编译!
把 miui_services0.jar 还是 miui_framework0.jar 这两个文件 push 到手机中。
j1s_r_dev/out/target/product/qssi/system/framework$ adb push miui_* system/framework
3. 配置 .rc 文件
创建 .rc 文件:init.miuidebug.rc
添加 miui_framework0.jar和miui_services0.jar 内容如下:
miui_framework0.jar 是有两处,miui_services0.jar 有一处。
# set up the global environment``on early-init`` ``export ANDROID_BOOTLOGO ``1`` ``export ANDROID_ROOT /system`` ``export ANDROID_ASSETS /system/app`` ``export ANDROID_DATA /data`` ``export ANDROID_STORAGE /storage`` ``export ANDROID_ART_ROOT /apex/com.android.art`` ``export ANDROID_I18N_ROOT /apex/com.android.i18n`` ``export ANDROID_TZDATA_ROOT /apex/com.android.tzdata`` ``export EXTERNAL_STORAGE /sdcard`` ``export ASEC_MOUNTPOINT /mnt/asec`` ``export BOOTCLASSPATH /apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/miui_framework0.jar:/system/framework/framework.jar:/system/framework/miuisdk``@boot``.jar:/system/framework/miuisystemsdk``@boot``.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/system/framework/tcmiface.jar:/system/framework/telephony-ext.jar:/system/framework/qcom.fmradio.jar:/system/framework/com.nxp.nfc.nq.jar:/system/framework/QPerformance.jar:/system/framework/UxPerformance.jar:/system/framework/WfdCommon.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar`` ``export DEX2OATBOOTCLASSPATH /apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/miui_framework0.jar:/system/framework/framework.jar:/system/framework/miuisdk``@boot``.jar:/system/framework/miuisystemsdk``@boot``.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/system/framework/tcmiface.jar:/system/framework/telephony-ext.jar:/system/framework/qcom.fmradio.jar:/system/framework/com.nxp.nfc.nq.jar:/system/framework/QPerformance.jar:/system/framework/UxPerformance.jar:/system/framework/WfdCommon.jar`` ``export SYSTEMSERVERCLASSPATH /system/framework/com.android.location.provider.jar:/system/framework/miui_services0.jar:/system/framework/services.jar:/system/framework/ethernet-service.jar:/apex/com.android.permission/javalib/service-permission.jar:/apex/com.android.wifi/javalib/service-wifi.jar:/apex/com.android.ipsec/javalib/android.net.ipsec.ike.jar
把 init.miuidebug.rc push 到手机中
adb push init.miuidebug.rc /system/etc/init/
其中 init.miuidebug_r.rc 文件是使用 pull 命令从手机取出来的
adb pull init.environ.rc
然后把 init.environ.rc 重命名 init.miuidebug_r.rc,高通的用高通的,MTK用 MTK 的,Q 用 Q 的, R 用 R 的,确保不出差错可以在源码对应的机型中 pull,pull 下来再修改,最起码保证高通和联发科的不要混用。
4. 移除 oat 和 arm 目录
rm -rf /system/framework/oat/` `rm -rf /system/framework/arm*
重启手机生效.
5. 参考
Framework本地快速编译调试(quickbuild): https://wiki.n.miui.com/pages/viewpage.action?pageId=281389018 Android源码编译框架(soong+kati)基本流程介绍: https://wiki.n.miui.com/pages/viewpage.action?pageId=477633339 Ninja 构建系统: https://blog.csdn.net/yujiawang/article/details/72627121
评论
-
Yankai1 Yang 杨艳凯 发表:
todo list: 优化首次编译时间。
-
耿如月 发表:
用ninja编说找不到
ninja: error: unknown target ‘miui_framework0’, did you mean ‘mini_framework’?
-
Yankai1 Yang 杨艳凯 发表:
修改 Android.bp 后需要重新 make 一下,然后再 ninja
-
-
方智荣 发表:
你好,修改完ActivityThread.java之后,用make miui_framework0 -j8会报“@UnsupportUsage找不到符号”的错误,是不是缺少了什么依赖?
-
刘吕平 发表:
miui_framework0 不能依赖service相关jar
加上依赖aosp 的framework就可以了
-
耿如月 发表:
libs里需要加上 "unsupportedappusage"- 回复
- 赞3人赞了它
- 十二月 21, 2020
-
郭楚谋 发表:
请教一下,在
make framework-minus-apex -j8 这一步的时候,报了如下的错误:
out/soong/Android-venus.mk: error: miui_services0: Installable device module must have LOCAL_SOONG_DEX_JAR set
请问是为什么呢?
-
郭楚谋 发表:
出现这个的原因是因为在 miui_service0 的 srcs 的文件为空,就会出现上面这个报错。
-
-
许晶泉 发表:
直接使用:
ninja miui_services0
找不到 ninja.build, 使用以下命令可以
prebuilts/build-tools/linux-x86/bin/ninja -f ./out/combined-venus.ninja miui_services0
- 回复
- 赞2人赞了它
- 一月 19, 2021
-
郭楚谋 发表:
跟各位分享一个教训,这个不要跟莫昌明大佬的一起混着用,不然你就会一直很疑惑,为什么我的改动没有任何的效果。