Android overlay机制的目的是为OEM厂商提供一种替换原生系统资源的机制,它允许在不修改packages中apk的情况下,来自定义 framework和package中的资源文件,实现资源的定制。
一、
RRO原理
应用运行时,通过 getString/getDrawable去调用某个资源,会将资源的resources ID 作为参数传给Framework层。Framework层查找资源时会使用这个resources ID,同时结合当前系统的configuration(分辨率、语言、横竖屏),即通过resources ID 和 configuration,系统首先会调用我们通过RRO添加的资源文件,并根据configuration使用最匹配的资源文件,如果此时没有找到文件,则再调用应用原生的资源文件。其原理如下图所示:
结合上图可以看出应用只是负责提供resource ID,系统会根据configuration中的配置(语言、分辨率等)去获取适当的资源来加载,这是两个不连续和独立的过程。RRO就发生在系统检索资源的过程中,而应用使用资源的接口不变。因此,通过RRO无需对应用做任何修改。
二、RRO实现
以替换\packages\apps\Settings下的资源为例(Settings.apk的包名为com.android.settings)
1、编写Overlay.apk
(1)在\packages\apps\目录下新建SettingsOverlay文件夹,SettingsOverlay目录新建res文件夹、Android.mk文件、AndroidManifest.xml文件。
![](https://i-blog.csdnimg.cn/blog_migrate/bb8584bb9bb6d239a11510db79acf823.png)
(2)res文件夹存放需要替换的字符串、素材、配置项等资源文件,哪里需要修改就将文件添加进去(比如需要修改英文下dlg_close,则将SettingsOverlay\res\values目录下strings.xml添加上需要替换的app_name;如果需要修改主界面Icon,则将替换SettingsOverlay\res\mipmap-dpi中的ic_launcher_settings.png)。
(3)Android.mk是编译配置项,在这里可以设置apk是编译条件、签名方式、编译输出路径等信息,如下为例
###############################################################################
# 调用本文件夹资源
LOCAL_PATH:= $(call my-dir)
# 清理变量
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := SettingsOverlay
LOCAL_MODULE_TAGS := optional
# 平台签名
LOCAL_CERTIFICATE := platform
# 调用本目录res文件夹资源
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
# overlay.apk输出路径,必须在vendor目录下,否则不生效
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/overlay
include $(BUILD_PACKAGE)
(4)
AndroidManifest.xml主要用于指定要替换的apk的包名,用android:targetPackage属性指定包名,android:priority指定优先级,由于同一apk可以被多个overlay.apk替换资源,那么哪个overlay优先级高,则最终取得就是最高优先级overlay.apk中的资源。
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 Google Inc. All Rights Reserved. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.settings.overlay">
<overlay android:targetPackage="com.android.settings" android:priority="10"/>
</manifest>
2、在android源码工程根目录执行命令 mmm packages/apps/SettingsOverlay/ 模块编译overlay
3、生成的SettingsOverlay.apk位于/out/target/product/xxx平台/system/vendor/overlay/SettingsOverlay下
4、将SettingsOverlay.apk push到设备的/system/vendor/overlay/SettingsOverlay目录下重启即可生效
三、RRO注意事项
1、生成的apk需要指定输出到vendor下才会生效
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/overlay
include $(BUILD_PACKAGE)
2、由于overlay替换的是资源文件,所以必须调用res目录资源文件
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
3、
android:priority范围是0-9999,过万就不生效了