Android 12系统源码_RRO机制(一)Runtime Resource Overlay机制实践

news2024/12/23 15:34:20

前言

Android的RRO(Runtime Resource Overlay)机制允许开发者在运行时替换或重写系统资源,例如布局、图标、字符串等。这个机制的目标是为了支持设备定制和主题化,特别是在不修改系统源代码的情况下。RRO通过在系统的资源上叠加一个额外的资源层,来实现个性化和品牌定制,而不需要修改原有的资源文件。通常,RRO被用于OEM厂商在其设备上定制UI和功能,或者在Android版本升级时保持兼容性。

RRO的工作原理是,通过在运行时将资源包(如APK文件)作为叠加层加载到系统中。这样,当应用请求某个资源时,Android首先检查叠加层中的资源,如果存在,则使用叠加层的版本,而不是默认的系统资源。RRO机制的优点是它减少了系统定制的复杂性,同时避免了对基础系统文件的修改。

这种机制最早是在Android 6.0(Marshmallow)中引入的,并且随着Android版本的升级得到了优化和增强。

一、RRO 换肤实践

1.1 创建目标应用

首先新建一个需要被换肤的应用工程RROApplication,该工程中只有一个简单的MainActivity,加载了一个activity_main.xml的布局文件,有三个TextView,引用了三个颜色资源,我们的目标是利用RRO机制替换这三个TextView的颜色。这个工程所产生的应用我们将其称为【目标应用】。
目标应用

1.2 创建资源包应用

1.2.1 新建资源包应用工程

再次新建一个独立的app工程,这个应用存在的意义就是放置【目标应用】的资源文件,它虽然是一个应用工程,但是不包含任何逻辑和业务,就只是用于存放资源文件。这个工程所产生的应用我们将其称为【资源包】。
资源包

1.2.2 配置 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rro.overlay">

    <overlay
        android:targetName="ThemeResources"
        android:priority="1"
        android:targetPackage="com.example.rro" />

    <application android:hasCode="false"/>

</manifest>

如果某个APK 的AndroidManifest.xml中包含 标记作为 标记的子项,该APK将被视为『资源包』 。

-【必需设定】android:targetPackage 用于指明 RRO 想要替换的『目标应用』。
-【必需设定】android:hasCode必须设定为 false。由于无法替换代码,因此 RRO 无法使用 DEX 文件。
-【非必需设定】android:targetName 用于指明 RRO 『目标应用』的可替换资源子集的名称。如果『目标应用』没有定义可替换资源集,此属性就不需要设定。

1.3 可替换资源集标签overlayable

1.3.1 目标应用使用overlayable标签标记允许被替换的资源

在 Android 10 或更高版本中,『目标应用』可以使用 标签公开一组允许 RRO 替换的资源,未被公开的资源,则不允许 RRO 替换。

<resources>
    <overlayable name="ThemeResources">
        <policy type="public">
            <item type="color" name="purple_200" />
            <item type="color" name="purple_500" />
            <item type="string" name="main_content" />
        </policy>
    </overlayable>
</resources>

一个 APK 可以定义多个overlayable 标签,但每个标签必须在该软件包中具有唯一的名称

1.3.2 资源包指定目标应用中允许被替换的标签

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rro.overlay">

    <overlay
        android:targetName="ThemeResources"
        android:priority="1"
        android:targetPackage="com.example.rro" />

    <application android:hasCode="false"/>

</manifest>

当目标应用定义 标签的时候,资源包的需满足以下条件:

  • 必须指定 targetName
  • 只能替换 标记中列出的资源。
  • 只能定位到一个 名称。

1.3.3 限制策略

使用标记可以在目标应用中对可替换资源施加限制。type属性指定叠加层必须满足哪些政策的要求才能替换包含的资源。支持以下类型:

  • public:任何叠加层均可替换相应资源。
  • system:系统分区上的任何叠加层均可替换相应资源。
  • vendor:vendor 分区上的任何叠加层均可替换相应资源。
  • product:product 分区上的任何叠加层均可替换相应资源。
  • signature:使用与目标 APK 相同的签名进行签名的任何叠加层均可替换相应资源。
<overlayable name="ThemeResources">
   <policy type="vendor" >
         <item type="string" name="main_content" />
   </policy>
   <policy type="product|signature"  >
        <item type="color" name="purple_200" />
   </policy>
</overlayable>

如需指定多个政策,请使用竖线 (|) 作为分隔符。 如果指定了多个政策,叠加层只需满足一个政策的要求即可替换 标记中列出的资源。

1.4 定义资源映射

1.4.1 Android 10或以下版本

在 Android 10 或更低版本中,系统是根据资源的名称进行资源替换,所以我们只需要在资源包中将需要替换的资源定义好即可。
Android11以前

1.4.2 Android 11或以上版本

在 Android 11 或更高版本中,Google推荐在『资源包』的res/xml 目录中创建一个文件overlays.xml,枚举出应覆盖的『目标应用』的资源值及其替换值。
Android11以后

注意,target标签中的color并没有带上@标记,他实际上仅仅是一个字符串而不是引用

然后在资源包的AndroidManifest.xml 中将android:resourcesMap 属性的值设置为资源映射文件。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.target.overlay.eleven">

    <overlay
        android:targetName="ThemeResources"
        android:targetPackage="com.android.target"
        android:resourcesMap="@xml/overlays"/>

    <application
        android:hasCode="false"/>

</manifest>

二、RRO换肤效果展示

2.1 构建安装包

在AndroidStudio中分别编译构建目标应用安装包和资源包应用安装包
安装包

2.2 安装目标应用

在我们安装完目标应用RROApplication-debug.apk之后,打开该应用,默认的显示效果如下所示。
目标应用默认显示效果

2.3 安装资源包应用

在我们安装完资源包应用RROResource-debug.apk之后,重新打开目标应用,会发现目标应用并不会发生什么变化,这是为什么呢?其实这是因为资源包应用的overlay功能开关默认没有被开启所导致的。

通过执行adb shelldumpsys overlay com.example.rro.overlay这条指令,可以得到以下关键信息。

com.example.rro.overlay:0 {
  mPackageName...........: com.example.rro.overlay
  mOverlayName...........: null
  mUserId................: 0
  mTargetPackageName.....: com.example.rro
  mTargetOverlayableName.: ThemeResources
  mBaseCodePath..........: /data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk
  mState.................: STATE_DISABLED
  mIsEnabled.............: false//注释1
  mIsMutable.............: true
  mPriority..............: 2147483647
  mCategory..............: null
  mIsFabricated..........: false
}
IDMAP OF com.example.rro.overlay
Paths:
    target path  : /data/app/~~B-NqptfXHZZHKfqYzQu-tg==/com.example.rro-8BHPMbRD_6ZPxdM6ZkYu3Q==/base.apk
    overlay path : /data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk
Debug info:
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/purple_700' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/teal_200' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/teal_700' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/black' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/white' in target: target resource has no overlayable declaration
Mapping://注释2
    0x7f05004a -> color 0xff000000 (color/purple_200)
    0x7f05004b -> color 0xff000000 (color/purple_500)
    0x7f0d001d -> string "RRO替换资源" (string/main_content)

在注释1处可以发现该资源包的overlay功能并没有被开启,因此目标应用对应的UI样式才没有发生变化。
在注释2处可以发现该资源包所要替换的具体资源条目信息。

2.4 为资源包应用开启overlay功能开关

执行cmd overlay enable com.example.rro.overlay可以为资源包开启overlay功能开关
然后再执行adb shelldumpsys overlay com.example.rro.overlay这条指令,可以得到以下关键信息。

dumpsys overlay com.example.rro.overlay
com.example.rro.overlay:0 {
  mPackageName...........: com.example.rro.overlay
  mOverlayName...........: null
  mUserId................: 0
  mTargetPackageName.....: com.example.rro
  mTargetOverlayableName.: ThemeResources
  mBaseCodePath..........: /data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk
  mState.................: STATE_ENABLED
  mIsEnabled.............: true//注释1
  mIsMutable.............: true
  mPriority..............: 2147483647
  mCategory..............: null
  mIsFabricated..........: false
}
IDMAP OF com.example.rro.overlay
Paths:
    target path  : /data/app/~~B-NqptfXHZZHKfqYzQu-tg==/com.example.rro-8BHPMbRD_6ZPxdM6ZkYu3Q==/base.apk
    overlay path : /data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk
Debug info:
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/purple_700' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/teal_200' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/teal_700' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/black' in target: target resource has no overlayable declaration
    W overlay '/data/app/~~dxlUScJmLwQ1fBFif8-PNw==/com.example.rro.overlay-1r-PLB3eA9jUEf00J1vPYw==/base.apk' is not allowed to overlay resource 'color/white' in target: target resource has no overlayable declaration
Mapping:
    0x7f05004a -> color 0xff000000 (color/purple_200)
    0x7f05004b -> color 0xff000000 (color/purple_500)
    0x7f0d001d -> string "RRO替换资源" (string/main_content)

可以发现注释1处,该资源包的overlay功能开关已经被开启,此事目标应用的显示效果也会发生变化。
在这里插入图片描述

三、启用/停用RRO功能

3.1 使用adb指令

adb shell cmd overlay enable [com.example.rro.overlay] // 开启
adb shell cmd overlay disable [com.example.rro.overlay] // 关闭

使用以上指令可以为特定包名的资源包开启或者关闭overlay功能。

3.2 使用系统api

OverlayManager overlayManager = context.getSystemService(OverlayManager.class);
OverlayInfo overlayInfo = manager.getOverlayInfo("com.example.rro.overlay", UserHandle.CURRENT_OR_SELF);
if(overlayInfo != null){
	//true为开启,false为关闭
	overlayManager.setEnabled("com.example.rro.overlay", true, UserHandle.CURRENT_OR_SELF);
};

可以在系统源码中直接使用OverlayManager提供的API可以启用、停用RRO,但是OverlayManager在公开的Android SDK中并没有提供,如果是使用Gradle构建工程,需要额外使用AOSP源码编译一个framework.jar并引入才可以使用,同时应用签名也需要使用Android系统签名,让应用成为系统级应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2252393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tomcat新手成长之路:安装部署优化全解析(下)

接上篇《Tomcat新手成长之路&#xff1a;安装部署优化全解析&#xff08;上&#xff09;》: link 文章目录 7.应用部署7.1.上下文7.2.启动时进行部署7.3.动态应用部署 8.Tomcat 类加载机制8.1.简介8.2.类加载器定义8.3.XML解析器和 Java 9.JMS监控9.1.简介9.2.启用 JMX 远程监…

动态代理如何加强安全性

在当今这个信息爆炸、网络无孔不入的时代&#xff0c;我们的每一次点击、每一次浏览都可能留下痕迹&#xff0c;成为潜在的安全隐患。如何在享受网络便利的同时&#xff0c;有效保护自己的隐私和信息安全&#xff0c;成为了每位网络使用者必须面对的重要课题。动态代理服务器&a…

python---面向对象-python中的实践(2)

如何定义一个类&#xff1f; class 类名:pass怎样通过类&#xff0c;创建出一个对象&#xff1f; 根据类创建对象one Money() 执行流程1. 类的定义2. 根据类&#xff0c;创建出一个对象3. 将对象的唯一标识返回class Money:passprint(Money.__name__) xxx Money print(xxx.…

数据结构-散列函数的构造方法

一.数字关键词 关键词存储应该尽可能的离散 直接定址法:利用线性函数,例如上面的例子,h(key)key-1990,key1990&#xff0c;这个就被存放在0的位置 数字分析法:关键字可能有很到位组成,每一位变化可能都不一样&#xff0c;有的位是不变的,就是说不同的对象这一位都是一样的,有的…

单点登录解决方案 CAS(Central Authentication Service)详解

目录 CAS 的工作原理 票据&#xff08;Ticket&#xff09;详解 CAS 的优势 CAS 的应用场景 小结 参考资料 Central Authentication Service&#xff08;中央认证服务&#xff0c;简称 CAS&#xff09;是一个开源的企业级单点登录&#xff08;Single Sign-On, SSO&#xf…

输入json 达到预览效果

下载 npm i vue-json-pretty2.4.0 <template><div class"newBranchesDialog"><t-base-dialogv-if"addDialogShow"title"Json数据配置"closeDialog"closeDialog":dialogVisible"addDialogShow":center"…

U盘文件夹变打不开的文件:深度解析、恢复策略与预防之道

一、U盘文件夹变打不开的文件现象解析 在日常使用U盘的过程中&#xff0c;我们时常会遇到这样的困扰&#xff1a;原本存储有序、可以轻松访问的文件夹&#xff0c;突然之间变成了无法打开的文件。这些文件通常以未知图标或乱码形式显示&#xff0c;双击或右键尝试打开时&#…

2025年软考-网络工程师新旧教程及考纲变化对比!

2025网工教材改版基本确认&#xff01;网络工程师一直是软考中级的热门科目。最近&#xff0c;官方发布了官方第六版的网工教材&#xff0c;本次出版在原有第五版的基础上做了大量的删减&#xff0c;并新增了部分新内容。明年的软考考纲大概率会根据这次的新版教材进行修改&…

视觉处理基础1

目录 一、CNN 1. 概述 1.1 与传统网络的区别 1.2 全连接的局限性 1.3 卷积思想 1.4 卷积的概念 1.4.1 概念 1.4.2 局部连接 1.4.3 权重共享 2. 卷积层 2.1 卷积核 2.2 卷积计算 2.3 边缘填充 2.4 步长Stride 2.5 多通道卷积计算 2.7 特征图大小计算方法 2…

大疆T100大载重吊运植保无人机技术详解

大疆T100作为一款大载重吊运植保无人机&#xff0c;融合了全新的AI和AR功能&#xff0c;旨在进一步提升安全性并满足喷洒、播撒、吊运等多种作业场景的需求。以下是对其技术的详细解析&#xff1a; 一、总体性能 最大起飞重量&#xff1a;149.9公斤 喷洒容量&#xff1a;75升…

Kylin Server V10 下 RocketMQ 主备自动切换模式部署

一、NameServer简介 NameServer 是一个注册中心,提供服务注册和服务发现的功能。NameServer 可以集群部署,集群中每个节点都是对等的关系,节点之间互不通信。 服务注册 Broker 启动的时候会向所有的 NameServer 节点进行注册,注意这里是向集群中所有的 NameServer 节点注册…

ESP32+VSCODE开发过程无法使用Debug调试问题解决

1.点击Debug按钮报错 Error: libusb_open() failed with LIBUSB_ERROR_ACCESS Error: esp_usb_jtag: could not find or open device! 2.解决办法 1.找见espidf的安装目录下的如下文件&#xff08;如下自己的安装目录&#xff09; home\fjq\esp-idf\espidfv5.3.1\tools\tool…

【CSS】一篇掌握CSS

不是因为有了希望才去坚持,而是坚持了才有了希望 目录 一.导入方式 1.行内样式 2.内部样式 3.外部样式(常用) 二.选择器 1.基本选择器(常用) 1.1标签选择器 1.2类选择器 1.3id选择器 2.层次选择器 2.1后代选择器 2.2子选择器 2.3相邻兄弟选择器 2.4通用兄弟选择器…

MySQL底层概述—6.索引原理

大纲 1.索引原理 2.二叉查找树 3.平衡二叉树(AVL树) 4.红黑树 5.B-Tree 6.BTree 7.Hash索引 8.聚簇索引与非聚簇索引 1.索引原理 索引会在数据文件中(ibd文件)&#xff0c;通过数据页(Page)进行存储。索引可以加快检索速度&#xff0c;但也会降低增删改速度&#xff0…

C语言学习笔记:循环结构

循环结构 什么是循环 代码的重复执行&#xff0c;就叫做循环。 循环的分类 无限循环&#xff1a;程序设计中尽量避免无限循环&#xff0c;其实就是死循环。程序中的无限循环必须是可控的。有限循环&#xff1a;循环限定循环次数或者循环的条件。 循环的构成&#xff1a; …

stable diffusion实践操作-大模型介绍:SD的发展历史,SD1.5和SDXL之间的差别

大家有没有这样的困惑&#xff1a;在找模型时&#xff0c;老是会出现一些奇怪的标签&#xff0c;像 sd1.5、sdxl 之类的模型后缀&#xff0c;真让人摸不着头脑&#xff0c;一会儿 1.0&#xff0c;一会儿 1.5&#xff0c;一会儿 XL&#xff0c;完全搞不清楚状况。今天就来给大家…

AI高中数学教学视频生成技术:利用通义千问、MathGPT、视频多模态大模型,语音大模型,将4个模型融合 ,生成高中数学教学视频,并给出实施方案。

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下AI高中数学教学视频生成技术&#xff1a;利用通义千问、MathGPT、视频多模态大模型&#xff0c;语音大模型&#xff0c;将4个模型融合 &#xff0c;生成高中数学教学视频&#xff0c;并给出实施方案。本文利用专家模…

PyCharm中Python项目打包并运行到服务器的简明指南

目录 一、准备工作 二、创建并设置Python项目 创建新项目 配置项目依赖 安装PyInstaller 三、打包项目 打包为可执行文件 另一种打包方式(使用setup.py) 四、配置服务器环境 五、上传可执行文件到服务器 六、在服务器上运行项目 配置SSH解释器 配置部署 上传代…

git clone超大仓库时报错:fatal: early EOF

环境版本&#xff1a; 系统&#xff1a;Ubuntu git版本&#xff1a;version 2.43.0 在执行git clone命令时报错&#xff0c;信息如下&#xff1a; 系统&#xff1a;Win10 git版本&#xff1a;version 2.47.0 解决办法1&#xff1a; 1、关闭压缩&#xff1a; git conf…

C++基础:list的基本使用

文章目录 1.基本构造和插入删除基本构造和尾插数据迭代器的分类内置排序sort任意位置插入删除 2.链表的合并,去重和剪切链表的合并链表去重链表的剪切 list的本质就是带头双向循环列表 1.基本构造和插入删除 基本构造和尾插数据 与之前vector的方法相同直接调用即可 迭代器的分…