Overlay机制

本文详细介绍了Android应用资源定制与Overlay机制的概念、原理及应用过程,包括配置类型、目录添加、资源文件创建等关键步骤。通过具体实例阐述了如何在不同产品中通过Overlay目录覆盖系统自带资源文件,以及如何检测修改后的资源文件,同时提供了多种工具的使用方法,如AAPT、apktools等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    Android overlay 机制允许在不修改packages中apk的情况下,来自定义 framework和package中的资源文件,实现资源的定制。来达到显示不同UI得目的(如MIUI)。 

    以下几类能够通过该机制定义:

  • Configurations (string, bool, bool-array)
  • Localization (string, string-array)
  • UI Appearance (color, drawable, layout, style, theme, animation)
  • 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

有两种不同的overaly目录定义,来影响最终的效果:

  • PRODUCT_PACKAGE_OVERLAYS: used by a particular product
  • DEVICE_PACKAGE_OVERLAYS: used several products that share a common device model

如果包含同一资源,那么 PRODUCT_PACKAGE_OVERLAYS 将覆盖 DEVICE_PACKAGE_OVERLAYS 中的, 这两个定义如下:

build/core/package.mk (Line: 93)

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)

 PRODUCT_PACKAGE_OVERLAYS & DEVICE_PACKAGE_OVERLAYS 功能是一样的,只是优先级不一样:

    PRODUCT_PACKAGE_OVERLAYS 优先于 DEVICE_PACKAGE_OVERLAYS 

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)

Or:

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系统自带package中资源文件, 那么在overlay目录下必须包含和要替换package相同的路径, 该路径是Android源码目录的相对路径.

For example, 如果我们想要替换以下目录的资源文件:

packages/apps/Settings/res/

那么在overlay目录下面必须创建一样的目录:

....../overlay目录/packages/apps/Settings/res/

然后放入想要替换的资源(必须和系统package相同路径和文件名).

注意:

  • For color, bool, string, array, style/theme types, the resource values are identifed by their keys, so for these types, there is no need to put the resources in a file with the same name as in the original base package.
  • For layout, animation, picture drawables and raw types, the resources are indentifed by their file name, and overlay for these resources should keep the file name same as in the base packages.

 

2 在APK中检测资源

   通过overlay改变apk资源文件并生成apk后,一般要检测生成的apk的资源是否已经改变了.

2.2 使用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.

 

For example:

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/


Apktool v1.5.0.5a056e3 - a tool for reengineering Android apk files
Copyright 2010 Ryszard Wi??niewski
with smali v1.3.4-ibot8, and baksmali v1.3.4-ibot8
Updated by iBotPeaches
Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
 
Usage: apktool [-q|--quiet OR -v|--verbose] COMMAND [...]
 
COMMANDs are:
 
    d[ecode] [OPTS] [
        Decode to
 
        OPTS:
 
        -s, --no-src
            Do not decode sources.
        -r, --no-res
            Do not decode resources.
        -d, --debug
            Decode in debug mode. Check project page for more info.
        -f, --force
            Force delete destination directory.
        -t , --frame-tag
            Try to use framework files tagged by .
        --keep-broken-res
            Use if there was an error and some resources were dropped, e.g.:
            "Invalid config flags detected. Dropping resources", but you
            want to decode them anyway, even with errors. You will have to
            fix them manually before building.
 
    b[uild] [OPTS] [] []
        Build an apk from already decoded application located in .
 
        It will automatically detect, whether files was changed and perform
        needed steps only.
 
        If you omit then current directory will be used.
        If you omit then /dist/
        will be used.
 
        OPTS:
 
        -f, --force-all
            Skip changes detection and build all files.
        -d, --debug
            Build in debug mode. Check project page for more info.
 
    if|install-framework []
        Install framework file to your system.
 
For additional info, see: https://github.com/iBotPeaches/brut.apktool
For smali/baksmali info, see: http://code.google.com/p/smali/

 

2.3 Using dumpres 

3 More on AAPT and Overlay

3.1 How overlay works

While building the package APKs, the overlay directories are passed to aapt command lines using -S options in the same order as they are defined in 

PRODUCT_PACKAGE_OVERLAYS and DEVICE_PACKAGE_OVERLAYS.

For example, while building the Settings APK, the following command are executed:

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

Note: some overlay directories that don't contain the Settings resources will be filtered first, and do not appear in the above command line.

 

3.2 Add extra resources in Overlay

Though not recommanded, we can add new resources in overlay directory, for example, if base package Settings doesn't define a bool value with key no_such_key, we can add it in the overlay file bool.xml like this:

    ... ...
    true
    ... ...

If the add-resource line is missing, aapt tool will complain while creating the apk file:

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.


Another way to avoid the complaint is to run aapt with the option:

--auto-add-overlay
    Automatically add resources that are only in overlays.


<think>嗯,用户想了解Android Overlay机制的学习资料和学习计划。用户提到了官方文档、源码注释、行业博客,还特别区分了静态和动态Overlay的应用场景。看来用户已经有一定基础概念,想系统性地深入学习。 用户可能是个Android系统开发工程师,或者是ROM定制开发者,正在为设备定制或主题换肤功能寻找底层实现方案。从提问的专业性来看,用户应该至少熟悉Android应用开发,现在想深入framework层。 关于Overlay机制,我需要重点梳理几个维度:首先是静态和动态的区别,静态Overlay(资源替换)和动态Overlay(运行时主题切换)的实现原理完全不同;其次是权限控制,系统级和普通应用的Overlay权限差异很大;最后是实际应用场景,比如主题引擎、多语言支持、设备定制等。 官方文档方面,AOSP的resource-overview确实是最权威的,但比较分散。源码层要重点看ResourceManagerService和OverlayManagerService这两个类。行业博客里Gityuan的分析最透彻,不过需要用户有Binder和AMS的基础知识。 用户可能没意识到的是Overlay的安全风险,比如恶意覆盖系统资源,这点在CTS测试中有严格要求。还有Overlay资源冲突的排查方法也很实用,比如用aapt查看优先级。 学习计划要循序渐进:先理解资源系统基础,再区分静/动态机制,最后结合实际调试。用户如果真能按计划研究源码注释,至少需要两周时间,特别是动态Overlay涉及到的Binder调用链比较深。不过从用户提问的精准度看,应该能hold住。</think>以下是为您制定的Android Overlay机制系统学习计划,结合官方资料与行业实践: --- ### **Android Overlay机制学习路径** #### **第一阶段:基础概念建立 (1-2天)** 1. **官方核心文档** - [AOSP资源覆盖文档](https://source.android.com/docs/core/runtime/rros)(重点理解`<overlay>`标签) - [动态覆盖API指南](https://developer.android.com/reference/android/content/om/OverlayManager)(Android 10+) - 关键源码路径: ```bash frameworks/base/core/java/android/content/om/OverlayManager.java frameworks/base/services/core/java/com/android/server/om/* ``` 2. **行业权威解析** - [Gityuan:Overlay机制原理](http://gityuan.com/2017/02/11/android-resource/)(源码层剖析) - [XDA:Overlay开发实践](https://forum.xda-developers.com/t/guide-theming-with-overlays.3166910/)(含RRO示例) #### **第二阶段:静态/动态Overlay对比 (3天)** | **特性** | **静态Overlay (RRO)** | **动态Overlay (RROS)** | |-------------------|-------------------------------------|--------------------------------------| | **生效时机** | 系统启动时加载 | 运行时实时切换 | | **修改权限** | 需系统签名 | 需`OVERLAY_PRODUCTION`权限 | | **配置文件** | `AndroidManifest.xml`声明overlay | `OverlayManager#setEnabled`动态控制 | | **典型场景** | 厂商主题预置 | 动态主题切换/AB测试 | | **资源更新** | 需重启生效 | 实时生效 | #### **第三阶段:实战与调试 (2天)** 1. **静态Overlay开发示例** ```xml <!-- AndroidManifest.xml --> <manifest xmlns:android="..." package="com.example.overlay"> <overlay android:targetPackage="com.android.settings" android:priority="1"/> </manifest> ``` ```bash # 编译后验证覆盖效果 adb shell cmd overlay list ``` 2. **动态Overlay API调用** ```java OverlayManager om = getSystemService(OverlayManager.class); om.setEnabled("com.example.dynamic_overlay", true, USER_SYSTEM); ``` 3. **资源冲突排查工具** ```bash aapt dump resources <apk-path> | grep overlay ``` #### **第四阶段:进阶应用场景 (2天)** 1. **多语言覆盖** 通过覆盖`values-<lang>`目录实现定制翻译 2. **设备定制** 替换`/res/xml/config.xml`修改系统参数 3. **主题引擎** 动态切换`colorPrimary`等属性实现夜间模式 4. **A/B测试** 动态加载不同UI布局覆盖原界面 --- ### **关键学习资料** 1. **[官方Overlay设计文档](https://source.android.com/docs/core/architecture/rros)** (含架构图与权限控制逻辑) 2. **[OverlayManagerService源码](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/om/)** (核心逻辑在`OverlayManagerServiceImpl.java`) 3. **CTS覆盖测试用例** `android.app.cts.OverlayHostTest`(验证兼容性) --- ### **常见问题解决方案** 1. **覆盖失效** - 检查`targetPackage`拼写错误 - 验证`overlay`与目标APK签名一致性 2. **资源冲突** - 使用`adb shell dumpsys overlay`查看加载顺序 - 调整`android:priority`数值(值越大优先级越高) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值