前言
Android的构建系统中,有一些机制和工具可以帮助我们实现源代码的定制和优化,例如:
- overlay:这是一种用于修改或替换系统资源(如字符串、图标、布局等)的机制。可以在不修改源代码的情况下,实现对系统资源的定制和优化。
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
在本文中,将介绍这些机制和工具的基本概念和用法,并且通过一些实例来展示如何使用它们来实现Android源代码的定制和优化。还将介绍如何调试我们的修改是否生效,以及如何查看我们的修改的详细信息。
1. 如何自定义overlay目录
在Android中,overlay是一种用于修改或替换系统资源(如字符串、图标、布局等)的机制。overlay可以在不修改源代码的情况下,实现对系统资源的定制和优化。overlay通常位于设备相关或厂商相关的目录下,例如:
device/rockchip/common/overlay
vendor/customize/rk3568_s_beta/overlay
(这是自定义的目录)
当构建系统生成系统镜像时,它会根据不同的目标平台和产品选择相应的overlay目录,并将其添加到DEVICE_PACKAGE_OVERLAYS
变量中。这个变量用于指定哪些目录包含了overlay资源。
# 这是系统默认的 DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay
因为我这个是customize.mk
是被 device/rockchip/rk356x/device.mk
包含的,所以我测试过在vendor/customize/customize.mk
中打印$(LOCAL_PATH)
结果是device/rockchip/rk356x
。如果想使用$(LOCAL_PATH)
并确保它指向正确的目录,需要确保尝试访问它之前没有其他Makefile修改它,并且是直接从构建系统中调用vendor/customize/customize.mk
,而不是从另一个Makefile中包含它。
所以自定义一个变量MY_CUSTOM_PATH := $(TOP)/vendor/customize
打印出来就是./vendor/customize
MY_CUSTOM_PATH := $(TOP)/vendor/customize $(warning Enter $(MY_CUSTOM_PATH)/rk3568_s_beta) # 这句话的意思就是加载当前设备厂商的overlay路径./vendor/customize/rk3568_s_beta/overlay DEVICE_PACKAGE_OVERLAYS += $(MY_CUSTOM_PATH)/rk3568_s_beta/overlay
这样当执行make
时,构建系统会将这目录都加入到overlay资源的搜索路径中。
当一个系统资源在多个overlay目录中都被修改或替换时,它们可能会产生冲突和覆盖。为了避免这种情况,Android的构建系统提供了一些规则和工具来检查和处理资源的冲突和覆盖。
资源的覆盖顺序是由DEVICE_PACKAGE_OVERLAYS
变量中指定的目录顺序决定的。也就是说,后面指定的目录会覆盖前面指定的目录中相同名称和类型的资源。
- 来测试下 比如系统SettingsProvider叫做
def_bluetooth_on
,它用于指定蓝牙是否默认开启。它在以下几个地方被定义和赋值:
# 这是系统源码目录下的 ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk/frameworks/base/packages/SettingsProvider$ grep -rn "def_bluetooth_on" src/com/android/providers/settings/DatabaseHelper.java:2476: R.bool.def_bluetooth_on); res/values/defaults.xml:39: <bool name="def_bluetooth_on">true</bool> # 源码默认overlay部分: ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk/device/rockchip$ grep -rn "def_bluetooth_on" common/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:22: <bool name="def_bluetooth_on">false</bool> common/overlay_go/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:26: <bool name="def_bluetooth_on">false</bool> rk356x/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:26: <bool name="def_bluetooth_on">false</bool> # 自定义overlay部分,这里我明明是写的true,但我编译测试发现蓝牙还是没有默认打开 ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk/vendor/customize$ grep -rn "def_bluetooth_on" rk3568_s_beta/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:27: <bool name="def_bluetooth_on">true</bool>
我怀疑是因为有几个overlay的地方 疑点 : 一个是device/rockchip/
common/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml ,二是/vendor/customize/
rk3568_s_beta/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
- 在
device/rockchip/common/overlay
目录中,有一个资源文件叫做defaults.xml
,它用于修改或替换系统资源。它在以下地方修改了def_bluetooth_on
的值为false
:
device/rockchip/common/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:22: <bool name="def_bluetooth_on">false</bool>
- 在
vendor/customize/rk3568_s_beta/overlay
目录中,我自定义了overlay目录 也有一个资源文件叫做defaults.xml
,它用于修改或替换系统资源。它在以下地方修改了def_bluetooth_on
的值为true
:
rk3568_s_beta/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:27: <bool name="def_bluetooth_on">true</bool>
我最开始理解是执行
make
时,构建系统会将这以上这几个目录都加入到overlay资源的搜索路径中,并按照它们在DEVICE_PACKAGE_OVERLAYS
变量中的顺序来处理资源的覆盖。因为先指定了device/rockchip/common/overlay
,然后指定了vendor/customize/rk3568_s_beta/overlay
,所以后者会覆盖前者中相同名称和类型的资源。也就是说,最终生成的系统镜像中,def_bluetooth_on
的值会被设置为true,但结果还是false。。。
后面实际测试,压根不是跟理解是一样的,所以我打算先注释掉系统厂商目录原有的overlay目录,只走自定义的overlay目录。
+++ b/device/rockchip/rk356x/rk3568_s/rk3568_s.mk @@ -13,7 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # # First lunching is S, api_level is 31 PRODUCT_SHIPPING_API_LEVEL := 31 PRODUCT_DTBO_TEMPLATE := $(LOCAL_PATH)/dt-overlay.in @@ -26,7 +31,7 @@ $(call inherit-product, device/rockchip/rk356x/device.mk) $(call inherit-product, device/rockchip/common/device.mk) $(call inherit-product, frameworks/native/build/tablet-10in-xhdpi-2048-dalvik-heap.mk) -DEVICE_PACKAGE_OVERLAYS += $(LOCAL_PATH)/../overlay +#DEVICE_PACKAGE_OVERLAYS += $(LOCAL_PATH)/../overlay PRODUCT_CHARACTERISTICS := tablet ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ git diff device/rockchip/common/BoardConfig.mk diff --git a/device/rockchip/common/BoardConfig.mk b/device/rockchip/common/BoardConfig.mk index 4724a3bd46..d164031bf5 100755 --- a/device/rockchip/common/BoardConfig.mk +++ b/device/rockchip/common/BoardConfig.mk @@ -199,12 +199,12 @@ VENDOR_SECURITY_PATCH := $(PLATFORM_SECURITY_PATCH) TARGET_BOOTLOADER_BOARD_NAME ?= rk30sdk TARGET_NO_BOOTLOADER ?= true -ifeq ($(filter atv box, $(strip $(TARGET_BOARD_PLATFORM_PRODUCT))), ) -DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay -ifneq ($(BOARD_HAS_RK_4G_MODEM), true) -DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay_wifi_only -endif -endif +#ifeq ($(filter atv box, $(strip $(TARGET_BOARD_PLATFORM_PRODUCT))), ) +#DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay +#ifneq ($(BOARD_HAS_RK_4G_MODEM), true) +#DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay_wifi_only +#endif +#endif
2.调试overlay资源是否生效
当我们修改或替换了系统资源后,可能想要验证我们的修改是否正确地应用到了系统镜像中。为了快速调试做到这一点,可以使用一些工具来查看系统镜像中的资源信息,比较它们和我们的overlay资源是否一致。
一个常用的工具是aapt
,它是一个用于处理Android应用程序包的命令行工具。它可以用于查看、添加、删除或修改APK中的资源和元数据。可以使用aapt
来查看系统镜像中的某个APK文件中的资源信息,例如:
aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk
这个命令会打印出SettingsProvider.apk
中所有的资源信息,包括资源名称、ID、类型、值、大小、引用等。如果我们想要查看某个特定的资源,我们可以使用grep
命令来过滤输出,例如:
aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk | grep def_bluetooth_on
这个命令会打印出与def_bluetooth_on
相关的资源信息,例如:
ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk | grep def_bluetooth_on spec resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: flags=0x00000000 resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: t=0x12 d=0xffffffff (s=0x0008 r=0x00)
这个输出表示def_bluetooth_on
是一个布尔类型的资源,其值为true
(0xffffffff)。可以根据这个输出来判断我们的overlay资源是否生效。
vendor\customize\rk3568_s_beta\overlay\frameworks\base\packages\SettingsProvider\res\values\defaults.xml
中修改def_bluetooth_on
为<bool name="def_bluetooth_on">true</bool>
编译后看到以下输出:
ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk | grep def_bluetooth_on spec resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: flags=0x00000000 resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: t=0x12 d=0xffffffff (s=0x0008 r=0x00)
那么说明我们的overlay资源生效了,最终我实际测试也发现了,开机默认打开了蓝牙。
vendor\customize\rk3568_s_beta\overlay\frameworks\base\packages\SettingsProvider\res\values\defaults.xml
中修改def_bluetooth_on
为<bool name="def_bluetooth_on">false</bool>
ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk | grep def_bluetooth_on spec resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: flags=0x00000000 resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: t=0x12 d=0x00000000 (s=0x0008 r=0x00)
那么说明overlay资源生效了,但结果是def_bluetooth_on
为关闭的。
为了方便地比较不同overlay设置下的资源信息,用一个表格来展示方便对比:
资源名 | 资源ID | 类型 | 值 | 大小 | 资源的引用 |
com.android.providers.settings:bool/def_bluetooth_on(overlay set to true) | 0x7f02000d | bool | 0xffffffff (true) | 0x0008 | 0x00 |
com.android.providers.settings:bool/def_bluetooth_on(overlay set to false) | 0x7f02000d | bool | 0x00000000 (false) | 0x0008 | 0x00 |
0xffffffff
通常在这种上下文中表示true
。0x00000000
表示false
。r=0x00
:这是资源的引用。在这种情况下,它是0,这意味着资源不引用其他资源。
测试
vendor\customize\rk3568_s_beta\overlay\frameworks\base\packages\SettingsProvider\res\values\defaults.xml
中添加,这个目的是想默认打开wifi,蓝牙,默认背光244。
<resources> <bool name="def_wifi_on">true</bool> <bool name="def_bluetooth_on">true</bool> <integer name="def_screen_brightness">244</integer> </resources>
vendor\customize\rk3568_s_beta\overlay\frameworks\base\core\res\res\drawable-sw720dp-nodpi
中添加default_wallpaper.png
,这个目的是想overlay桌面壁纸。
OK , 编译烧机测试 结果和烧录前一致,这是因为我在编译后通过aapt
就知道了烧录后的结果,也再也不用担心系统默认的overlay会覆盖导致改代码混乱了。
总结
在本文中介绍了Android源代码定制的一些机制和工具,包括:
- overlay:介绍了overlay的概念和目录结构,以及如何自定义overlay目录和资源。
- 调试工具:介绍了
aapt
工具的用法,以及如何查看系统镜像中的资源信息。
希望这篇文章能够对你有所帮助,如果你有任何问题或建议,请在评论区留言。谢谢!