android资源文件overlay


aapt

aapt stands for Android Asset Packaging Tool. This tool is part of the SDK (and build system) and allows you to view, create, and update Zip-compatible archives (zip, jar, apk). It can also compile resources into binary assets.

aapt在android中主要打包资源文件等,在definitions.mk中,aapt使用了-S PRIVATE_RESOURCE_DIR去包含资源文件,而PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR),所以资源文件都包含在LOCAL_RESOURCE_DIR中。

// build\core\definitions.mk
# This rule creates the R.java and Manifest.java files, both of which
# are PRODUCT-neutral.  Don't pass PRIVATE_PRODUCT_AAPT_CONFIG to this invocation.
define create-resource-java-files
@mkdir -p $(PRIVATE_SOURCE_INTERMEDIATES_DIR)
@mkdir -p $(dir $(PRIVATE_RESOURCE_PUBLICS_OUTPUT))
$(hide) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m \
    $(eval # PRIVATE_PRODUCT_AAPT_CONFIG is intentionally missing-- see comment.) \
    $(addprefix -J , $(PRIVATE_SOURCE_INTERMEDIATES_DIR)) \
    $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
    $(addprefix -P , $(PRIVATE_RESOURCE_PUBLICS_OUTPUT)) \
    $(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
    $(addprefix -A , $(PRIVATE_ASSET_DIR)) \
    $(addprefix -I , $(PRIVATE_AAPT_INCLUDES)) \
    $(addprefix -G , $(PRIVATE_PROGUARD_OPTIONS_FILE)) \
    $(addprefix --min-sdk-version , $(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
    $(addprefix --target-sdk-version , $(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
    $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-code , $(PLATFORM_SDK_VERSION))) \
    $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION))) \
    $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
    $(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR))
endef

-S 参数用来指定资源文件,搜索多个目录,从左到右,找到第一个匹配的

   -S  directory in which to find resources.  Multiple directories will be scanned
       and the first match found (left to right) will take precedence.

overlay的是资源

关于android中资源的定义http://developer.android.com/guide/topics/resources/index.html中有详细的介绍,而overlay的主要作用就是为了替换apk中的资源文件(随便定义一个txt,并不能算资源文件),例如,frameworks\base\core\res\res\values\strings.xml中就定义了很多framework中需要用到的资源(resources ,string),假设其中有4条资源,

//frameworks\base\core\res\res\values\strings.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">

    <string name="byteShort">B</string>

    <string name="kilobyteShort">KB</string>

    <string name="megabyteShort">MB</string>

    <string name="gigabyteShort">GB</string>
</resources>    

在开发中,可以在其他地方定义PRODUCT_PACKAGE_OVERLAYS,新建一个strings.xml,修改其中的某个资源的的属性值,

// 其他overlay目录\frameworks\base\core\res\res\values\strings.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="gigabyteShort">gb</string>
</resources>    

这样编译完成后,gigabyteShort会变成修改后的值,其他3个值不变。

// overlay后的资源文件
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">

    <string name="byteShort">B</string>

    <string name="kilobyteShort">KB</string>

    <string name="megabyteShort">MB</string>
    //这条变化了
    <string name="gigabyteShort">gb</string>
</resources>    

在这里overlay替换的是资源,而不是文件。所以即使新建的string.xml中仅有1条修改,最终编译后的资源文件中其他3条保持不变。

默认情况下,overlay目录的资源文件内容只能覆盖原有软件包中的资源,而不能新增资源。不然会造成编译错误。
但是也有2种方法规避
1.原资源文件中也添加上该资源(这样就不算新增了),
2.一种更加简便的方法是给aapt命令增加–auto-add-overlay选项。

overlay的也可能是文件

最近在修改frameworks\base\core\res\res\xml\power_profile.xml中电池总电量的数值,将battery.capacity修改为3500mA,下面是对应的overlay文件,只添加了一条。

<device name="Android">
<item name="battery.capacity">3500</item>
</device>

但是修改完成后发现问题,设置—电池—上次充满后的电量使用情况一直是没有电池使用情况。查看相关代码发现,
只有在power_profile.xml中的screen.full大于10才会去refresh电量使用情况。

// packages\apps\Settings\src\com\android\settings\fuelgauge\PowerUsageSummary.java

  private void refreshStats() {

        final PowerProfile powerProfile = mStatsHelper.getPowerProfile();
        final BatteryStats stats = mStatsHelper.getStats();
        // power profile就是上面的power_profile.xml
        // screen.full
        final double averagePower = powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);
        // MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10;
        // screen.full所对应的值必须大于10才会去refresh电量使用情况
        if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP) {
       ...........
        }
        if (!addedSome) {
            addNotAvailableMessage();
        }

        BatteryEntry.startRequestQueue();
    }

而out目录下生成的资源文件中,power_profile.xml只有battery.capacity这一条(没有对应的screen.full这条,所以才不会去显示电量使用情况),所以这时候也可以说是文件覆盖了,仔细查看原power_profile.xml中的内容,发现其格式并不是android所规定的资源文件,而是一个特殊的xml文件,这时候就不是overlay资源了,而是类似于替换文件。
同时查看frameworks\base\core\res\res\xml\power_profile.xml原生的参数值,发现screen.full为0.1,也不是大于10,为何在没添加power_profile.xml这个overlay文件时,功能一切正常?

<item name="screen.full">0.1</item>

搜索整个代码(高通8939平台),发现DEVICE_PACKAGE_OVERLAYS中有对power_profile.xml的overlay,其中是高通自己定义的一些电池的参数,其中screen.full为261。

// device\qcom\msm8916_64\msm8916_64.mk
DEVICE_PACKAGE_OVERLAYS := device/qcom/msm8916_64/overlay

那么既然高通本身有对power_profile.xml的overlay,自己添加的overlay将高通的覆盖了?在package_internal.mk中,

 // build\core\package_internal.mk中
 // PRODUCT_PACKAGE_OVERLAYS排在DEVICE_PACKAGE_OVERLAYS前面,
 // 所以PRODUCT_PACKAGE_OVERLAYS 优先于 DEVICE_PACKAGE_OVERLAYS
 package_resource_overlays := $(strip \
    $(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 := $(package_resource_overlays) $(LOCAL_RESOURCE_DIR)

从上面可以看出,PRODUCT_PACKAGE_OVERLAYS 优先于 DEVICE_PACKAGE_OVERLAYS,而aapt -S会从左到右搜索资源文件,所以PRODUCT_PACKAGE_OVERLAYS中定义的会优先被匹配
所以最终的修改方法是:
1.将高通DEVICE_PACKAGE_OVERLAYS中的power_profile.xml拷贝一份到自己的overlay目录中(电池等的参数,不同的设备厂商的参数不同,因此以设备厂商的为准,而不用原生的power_profile.xml),
2.在此power_profile.xml的基础上添加或者修改其中的参数。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android动态overlay是一种在运行时修改应用程序的外观和行为的方法。通过动态overlay,您可以在不修改原始应用程序代码的情况下,通过叠加(overlay)外部源文件来修改应用程序的界面元素、样式、布局和其他属性。 动态overlay的实现依赖于Android源覆盖机制。您可以创建一个独立的Overlay包(通常是一个apk文件),其中包含您想要叠加到目标应用程序上的源文件。这些源文件包括布局文件、样式文件、字符串等。 要使用动态overlay,您需要完成以下步骤: 1. 创建Overlay包:创建一个新的Android项目,将要覆盖的源文件添加到该项目中。 2. 定义Overlay配置:在Overlay包的res/values目录下创建一个名为"config.xml"的文件,并定义Overlay的配置信息,例如目标应用程序的包名和版本号。 3. 打包Overlay:将Overlay项目打包成apk文件。 4. 安装Overlay:将Overlay apk安装到设备上。 5. 激活Overlay:通过调用OverlayManagerService API,将Overlay应用程序与目标应用程序关联起来,并将Overlay应用程序激活。 一旦激活了Overlay,它将会覆盖目标应用程序的相应源,从而修改应用程序的外观和行为。您可以使用不同的Overlay应用程序来实现不同的修改效果,并且可以在运行时根据需要切换不同的Overlay。 请注意,动态overlay需要系统级权限才能进行操作,因此只有经过授权的应用程序才能够使用此功能。使用动态overlay时,务必小心处理和确保安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值