资源覆盖-overlay机制

1. SRO–Static resource overly(静态替换)
2. RRO–Runtime resource overlay (运行时替换)

静态 RRO

1.写配置文件

以下代码显示了一个示例 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.overlay">
    <application android:hasCode="false" />
    <overlay android:targetPackage="com.example.target"
                   android:isStatic="true"
                   android:priority="5"/>
</manifest>

在 Android 10 或更低版本中,使用以下清单属性配置叠加层的不可变性和优先级。

  • android:isStatic。当此布尔值属性的值设置为 true 时,叠加层会默认处于启用状态并且不可变,这会导致叠加层无法停用。

  • android:priority。当多个静态叠加层以相同的资源值为替换目标时,此数字属性的值(仅影响静态叠加层)将配置叠加层的优先级。数值越大表示优先级越高。

Android 11 中的变化请参考官网,因为我没有涉及到更改所以就不写进来了。

那么,问题来了,以上的配置文件AndroidManifest.xml放置到哪个目录呢?

当然是跟app所在的安装目录有关啦~

如果app是安装在product目录下,那么配置文件就放置在product/overlay/目录下。如果app安装在vendor目录下,那么配置文件就放置在vendor/overlay/目录下,以此类推啦

2.写覆盖的资源文件

我们在待编译的android.mk同级目录下,创建res目录,然后在然后在res目录中去创建即将覆盖系统资源的相同路径下的资源(图片,字符串等等)。

例如,res/values/string.xml下

<resources >
<bool name="config_hasRecents">true</bool>
</resources>

3.编写构建资源

为了让以上编写的文件动态生效,那么必须在android.mk或者bp文件中进行配置

先写资源配置目录android.bp

runtime_resource_overlay {
    name: "ExampleOverlay",
    sdk_version: "current",
}

然后将以上的资源文件和配置文件以及放入overlay文件中。

然后ExampleOverlay配置在android.mk文件中,那么在源码编译的时候就会立即生效啦~

动态 RRO

动态PRO和静态PRO不一样,需要生成对应的overlay apk,然后overlay apk里面的资源会去替换需要覆盖的资源,这样就达到了替换的方式,所以怎么生成overlay apk,以及怎么去配置是主要问题。

动态PRO的工作原理是将overlay apk中定义的资源映射到目标软件包中定义的资源。当应用尝试解析目标软件包中资源的值时,系统转而会返回目标资源映射到的叠加层资源的值。

在系统查找资源时overlay apk会比target apk优先查找,只有系统找到了更好的资源时一个候选资源才会被丢弃, 所以overlay apk中的资源被会优先使用。

这里写图片描述

 1.编写overlay apk

设置清单

如果某个软件包包含 <overlay> 标记作为 <manifest> 标记的子项,该软件包将被视为 RRO 软件包。

  • 必要 android:targetPackage 属性的值用于指明 RRO 想要叠加的软件包的名称。

  • 可选 android:targetName 属性的值用于指明 RRO 想要叠加的目标软件包的可叠加资源子集的名称。如果目标未定义可叠加资源集,此属性就不会显示。

以下代码展示了一个示例叠加层 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.overlay">
    <application android:hasCode="false" />
    <overlay android:targetPackage="com.example.target"
                   android:targetName="OverlayableResources"/>
</manifest>

2.定义资源映射

有两种方式

方式1:

  1. 在resource-overlay-sys目录中配置相同资源目录下的文件,例如res/values/string.xml
  2. 编写构建资源,跟静态PRO的流程一致,编写android.bp文件
    runtime_resource_overlay {
        name: "ExampleOverlay",
        sdk_version: "current",
    }
  3. 将android.bp文件配置到公共的overlay.mk中即可

方式2:

在 Android 11 或更高版本中,用于定义overlay资源映射的推荐机制是,在overlay apk的 res/xml 目录中创建一个文件,枚举应覆盖的目标资源及其替换值,然后将 <overlay> 清单标记的 android:resourcesMap 属性的值设置为对资源映射文件的引用。

以下代码显示了一个示例 res/xml/overlays.xml 文件。

<?xml version="1.0" encoding="utf-8"?>
<overlay xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- Overlays string/config1 and string/config2 with the same resource. -->
    <item target="string/config1" value="@string/overlay1" />
    <item target="string/config2" value="@string/overlay1" />

    <!-- Overlays string/config3 with the string "yes". -->
    <item target="string/config3" value="@android:string/yes" />

    <!-- Overlays string/config4 with the string "Hardcoded string". -->
    <item target="string/config4" value="Hardcoded string" />

    <!-- Overlays integer/config5 with the integer "42". -->
    <item target="integer/config5" value="42" />
</overlay>

以下代码显示了一个示例叠加层清单。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.overlay">
    <application android:hasCode="false" />
    <overlay android:targetPackage="com.example.target"
                   android:targetName="OverlayableResources"
                   android:resourcesMap="@xml/overlays"/>
</manifest>

构建软件包

runtime_resource_overlay {
    name: "ExampleOverlay",
    sdk_version: "current",
}

其实步骤都差不多,都是动态生成overlay的apk。

如何验证

由于RRO 可以修改资源,所以出于安全方面的考虑,只有"vendor/overlay"和“product/overlay”目录下的overlay apk才被接收。

推送的目录跟目标apk所在的目录是一致的,push到"vendor/overlay"还是“product/overlay”目录,根据目标apk所在的目录是一致的

当push到对应目录之后,重启机器即可看到生效了。

验证方式如下:

adb root
adb remount
adb reboot
adb root
adb remount
adb reboot
adb root
adb push <RRO name>.apk /vendor/overlay
adb reboot

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值