android overlay机制允许在不修改package和framework的情况下,自定义其中的资源,实现资源定制,主题定制。具体可定制的资源有:
(1),Configurations (string, bool, bool-array)
(2),Localization (string, string-array)
(3),UI Appearance (color, drawable, layout, style, theme, animation)
(4),Raw resources (audio, video, xml) For detailed introduction on Android application resources, please refer to:
http://developer.android.com/guide/topics/resources/available-resources.html
1. 为产品添加overlay目录
1.1 Product Overlays 和 Device Overlays
两种都是定义产品的overlay目录
PRODUCT_PACKAGE_OVERLAYS: used by a particular product
DEVICE_PACKAGE_OVERLAYS: used serveral products that share a common device model
如果包含同一资源,则PRODUCT_PACKAGE_OVERLAYS会覆盖DEVICE_PACKAGE_OVERLAYS中的。二者定义如下:
build/core/packages.mk
************************************
LOCAL_RESOURCE_DIR := \
$(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \
$(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
$(wildcard $(foreach dir, $(DEVICE_PACKAGE_OVERLAYS), \
$(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
$(LOCAL_RESOURCE_DIR)
两者的功能一致,不同的是优先级和范围。
1.2 修改makefile添加overlays编译项
为添加一个overlay目录,需要修改产品的makefile( for example: device/vendor-name/device-name/product-name.mk ),添加一下几行:
PRODUCT_PACKAGE_OVERLAYS := device/vendor-name/device-name/product-name/overlay
$(PRODUCT_PACKAGE_OVERLAYS)
或
DEVICE_PACKAGE_OVERLAYS := device/vendor-name/device-name/common/overlay
$(DEVICE_PACKAGE_OVERLAYS)
例如: device/vendor-name/device-name/device_base.mk中添加:
LOCAL_PATH := device/vendor-name/device-name
DEVICE_PACKAGE_OVERLAYS := $(LOCAL_PATH)/overlay
如果要定义多个overlays目录,需要用空格隔开。如果有多个目录,并且都包含统一资源的定义,那么将使用第一个定义的目录中的资源。
1.3 在overlay目录下创建资源文件
想覆盖android系统下,packages与framework中的资源文件,那么在overlay目录下西部宝航和要替换的资源文件相同的路径,该路径是android源码目录的相对路径。
例如:如果要想替换一下目录的资源文件: packages/apps/Settings/res
则在overlay目录下,必须创建一样的目录: packages/apps/Settings/res ,然后放入想要替换的资源。
注意:对于color, bool, string, array, style/theme类型的资源,是通过他们的键值识别其值,没有必要将他们放在和原目录中相同文件名的文件中;而对于layout, animation, picture drawables and raw类型的文件是通过他们的文件名来识别的,所以在overlay目录中,对这些资源需要保证资源的名称与原基础目录中的名称一致。
2. 在apk中检查资源
通过overlay改变apk资源文件并生成apk后,一般需要检测生成的apk资源是否已经改变了。
2.1 通过AAPT检测
Usage: aapt l[ist] [-v] [-a] file.{zip,jar,apk} List contents of Zip-compatible archive.
aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
badging Print the label and icon for the app declared in APK.
permissions Print the permissions from the APK.
resources Print the resource table from the APK.
configurations Print the configurations in the APK.
xmltree Print the compiled xmls in the given assets.
xmlstrings Print the strings of the given compiled xml assets.
例如:
1. To dump string, bool values: aapt dump resources Settings.apk
2. To dump a raw xml file: aapt dump xmltree Settings.apk res/xml/appwidget_info.xml
3. To dump the current configurations/localizations: aapt dump configurations Settings.apk
2.2 使用apktools检测
Reference: http://code.google.com/p/android-apktool/
3. 关于 AAPT和Overlay
3.1 overlay工作机制
当创建一个apk时,overlay目录是通过aapt命令行-S,加上他们在 PRODUCT_PACKAGE_OVERLAYS and DEVICE_PACKAGE_OVERLAYS.中定义的参数,实现资源文件的替换。
例如在创建一个Settings.apk时,会执行如下 的指令:
************************************************************************
out/host/linux-x86/bin/aapt package -u -z \ -M packages/apps/Settings/AndroidManifest.xml \ -S device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res \ -S vendor/vendor-name/media/common/overlay/packages/apps/Settings/res -S packages/apps/Settings/res \ -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \ --min-sdk-version 16 --target-sdk-version 16 --product default \ --version-code 16 --version-name 4.1.2-eng.xxxx.20121121.152327 \ -F out/target/product/product-name/obj/APPS/Settings_intermediates/package.apk ************************************************************************
注意:一些不宝航Settings资源的overlay目录会被首先过滤掉,不会出现命令中。
3.2 添加额外的资源在Overlay
尽管不推荐,我们可以在overlay目录下添加新的资源,例如,如果在Settings中没有定义no_such_key的资源,可以在bool.xml中定义:
<add-resource type="dimen" name="custom_cling_margin_top" />
<bool name="no_such_key">false</bool>
在打包的阶段,会报:
device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res/values/bools.xml:30: error: Resource at no_such_key appears in overlay but \
not in the base package; use to add.
另外避免这种报错的方法,在可以运行aapt命令,在overlays添加参数 --auto-add-overlay , 让其在打包的时候自动添加资源
(1),Configurations (string, bool, bool-array)
(2),Localization (string, string-array)
(3),UI Appearance (color, drawable, layout, style, theme, animation)
(4),Raw resources (audio, video, xml) For detailed introduction on Android application resources, please refer to:
http://developer.android.com/guide/topics/resources/available-resources.html
1. 为产品添加overlay目录
1.1 Product Overlays 和 Device Overlays
两种都是定义产品的overlay目录
PRODUCT_PACKAGE_OVERLAYS: used by a particular product
DEVICE_PACKAGE_OVERLAYS: used serveral products that share a common device model
如果包含同一资源,则PRODUCT_PACKAGE_OVERLAYS会覆盖DEVICE_PACKAGE_OVERLAYS中的。二者定义如下:
build/core/packages.mk
************************************
LOCAL_RESOURCE_DIR := \
$(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \
$(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
$(wildcard $(foreach dir, $(DEVICE_PACKAGE_OVERLAYS), \
$(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
$(LOCAL_RESOURCE_DIR)
两者的功能一致,不同的是优先级和范围。
1.2 修改makefile添加overlays编译项
为添加一个overlay目录,需要修改产品的makefile( for example: device/vendor-name/device-name/product-name.mk ),添加一下几行:
PRODUCT_PACKAGE_OVERLAYS := device/vendor-name/device-name/product-name/overlay
$(PRODUCT_PACKAGE_OVERLAYS)
或
DEVICE_PACKAGE_OVERLAYS := device/vendor-name/device-name/common/overlay
$(DEVICE_PACKAGE_OVERLAYS)
例如: device/vendor-name/device-name/device_base.mk中添加:
LOCAL_PATH := device/vendor-name/device-name
DEVICE_PACKAGE_OVERLAYS := $(LOCAL_PATH)/overlay
如果要定义多个overlays目录,需要用空格隔开。如果有多个目录,并且都包含统一资源的定义,那么将使用第一个定义的目录中的资源。
1.3 在overlay目录下创建资源文件
想覆盖android系统下,packages与framework中的资源文件,那么在overlay目录下西部宝航和要替换的资源文件相同的路径,该路径是android源码目录的相对路径。
例如:如果要想替换一下目录的资源文件: packages/apps/Settings/res
则在overlay目录下,必须创建一样的目录: packages/apps/Settings/res ,然后放入想要替换的资源。
注意:对于color, bool, string, array, style/theme类型的资源,是通过他们的键值识别其值,没有必要将他们放在和原目录中相同文件名的文件中;而对于layout, animation, picture drawables and raw类型的文件是通过他们的文件名来识别的,所以在overlay目录中,对这些资源需要保证资源的名称与原基础目录中的名称一致。
2. 在apk中检查资源
通过overlay改变apk资源文件并生成apk后,一般需要检测生成的apk资源是否已经改变了。
2.1 通过AAPT检测
Usage: aapt l[ist] [-v] [-a] file.{zip,jar,apk} List contents of Zip-compatible archive.
aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
badging Print the label and icon for the app declared in APK.
permissions Print the permissions from the APK.
resources Print the resource table from the APK.
configurations Print the configurations in the APK.
xmltree Print the compiled xmls in the given assets.
xmlstrings Print the strings of the given compiled xml assets.
例如:
1. To dump string, bool values: aapt dump resources Settings.apk
2. To dump a raw xml file: aapt dump xmltree Settings.apk res/xml/appwidget_info.xml
3. To dump the current configurations/localizations: aapt dump configurations Settings.apk
2.2 使用apktools检测
Reference: http://code.google.com/p/android-apktool/
3. 关于 AAPT和Overlay
3.1 overlay工作机制
当创建一个apk时,overlay目录是通过aapt命令行-S,加上他们在 PRODUCT_PACKAGE_OVERLAYS and DEVICE_PACKAGE_OVERLAYS.中定义的参数,实现资源文件的替换。
例如在创建一个Settings.apk时,会执行如下 的指令:
************************************************************************
out/host/linux-x86/bin/aapt package -u -z \ -M packages/apps/Settings/AndroidManifest.xml \ -S device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res \ -S vendor/vendor-name/media/common/overlay/packages/apps/Settings/res -S packages/apps/Settings/res \ -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \ --min-sdk-version 16 --target-sdk-version 16 --product default \ --version-code 16 --version-name 4.1.2-eng.xxxx.20121121.152327 \ -F out/target/product/product-name/obj/APPS/Settings_intermediates/package.apk ************************************************************************
注意:一些不宝航Settings资源的overlay目录会被首先过滤掉,不会出现命令中。
3.2 添加额外的资源在Overlay
尽管不推荐,我们可以在overlay目录下添加新的资源,例如,如果在Settings中没有定义no_such_key的资源,可以在bool.xml中定义:
<add-resource type="dimen" name="custom_cling_margin_top" />
<bool name="no_such_key">false</bool>
在打包的阶段,会报:
device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res/values/bools.xml:30: error: Resource at no_such_key appears in overlay but \
not in the base package; use to add.
另外避免这种报错的方法,在可以运行aapt命令,在overlays添加参数 --auto-add-overlay , 让其在打包的时候自动添加资源