Android-Overlay机制

作用:

Android原生Framework和一些系统App大量的使用了资源文件,如配置config.xml,字符string.xml,布局layout.xml等。我们在定制Android时,往往需要定制其中的一些内容,但又不希望破坏原有的结构,这时候就可以使用Overlay机制。一般用于修改frameworks和packages目录。

Overlay有两种方案,静态Overlay和动态Overlay。

静态Overlay:

静态Overlay在编译整个Android源码时就进行了替换动作。

场景:修改frameworks/base/core/res/res/values/config.xml中的属性。

1. 在device/brcm/rpi4/下创建overlay目录及对应的文件。

device/brcm/rpi4/car/overlay/frameworks/base/core/res/res/values/config.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2015, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->

<!-- These resources are around just to allow their values to be customized
     for different hardware and product builds.  Do not translate. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- Enables the GnssTimeUpdate service. This is a switch for enabling Gnss time based
         suggestions to TimeDetector service. -->
    <bool name="config_enableGnssTimeUpdateService">false</bool>
</resources>

这里表示config_enableGnssTimeUpdateService将会替换framework中声明的值,以当前声明的为准。

2.在aosp_rpi4_car.mk中添加overlay路径

PRODUCT_PACKAGE_OVERLAYS += device/brcm/rpi4/car/overlay

$(call inherit-product, packages/services/Car/car_product/build/car.mk)

这里需要注意的是因为car.mk中也会去overlay这个属性值,因此我将自己的overlay路径添加在前面,前面的优先级会更高。overlay在编译时会在build/soong/java/android_resources.go中进行处理,具体优先级可查看代码实现。

  • PRODUCT_PACKAGE_OVERLAYS  > DEVICE_PACKAGE_OVERLAYS 
  • 相同类型情况下,先添加的 > 后添加的

动态Overlay:

不同于静态Overlay,动态Overlay在编译时同时会编译原本的值和修改的值,在运行时动态读取。

场景:修改frameworks/base/packages/SettingsProvider/res/values/defaults.xml

1. 在device/brcm/rpi4/下创建overlay目录及对应的文件。

overlay/
├── SettingsProviderRpiOverlay
│   ├── Android.bp
│   ├── AndroidManifest.xml
│   └── res
│       └── values
│           └── default.xml

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright (C) 2021-2022 KonstaKANG
**
** SPDX-License-Identifier: Apache-2.0
*/
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.providers.settings.rpi"
    android:versionCode="1"
    android:versionName="1.0" >
    <application android:hasCode="false" />
    <overlay
        android:targetPackage="com.android.providers.settings"
        android:isStatic="true"
        android:priority="0" />
</manifest>

package名字可以根据原始包名随便取一个。

targetPackage代表要替换的包名。如果是修改frameworks/res中的配置,那targetPackage设为"android"。

priority为优先级,数字越大,优先级越高,如果另外一个地方也对相同属性进行了overlay,就会比较优先级。

Android.bp

runtime_resource_overlay {
    name: "SettingsProviderRpiOverlay",
    resource_dirs: ["res"],
    sdk_version: "current",
    proprietary: true
}

default.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2009 The Android Open Source Project
     Copyright (C) 2021-2022 KonstaKANG

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<resources>

    <!-- Default screen brightness -->
    <integer name="def_screen_brightness">128</integer>

    <!-- Disable bluetooth by default -->
    <bool name="def_bluetooth_on">false</bool>

    <!-- Disable location by default -->
    <integer name="def_location_mode">0</integer>

    <!-- Disable the lockscreen -->
    <bool name="def_lockscreen_disabled">true</bool>

    <!-- Keep screen on at all times by default -->
    <bool name="def_stay_on_while_plugged_in">true</bool>

    <!-- No setup wizard -->
    <bool name="def_device_provisioned">true</bool>
    <bool name="def_user_setup_complete">true</bool>

</resources>

这部分最终会编译成为一个apk,放置到系统下:/vendor/overlay/SystemUIRpiOverlay.apk,运行时再动态读取里面的配置。

2. 在aosp_rpi4_car.mk中添加overlay模块

# Overlays
PRODUCT_PACKAGES += \
    SettingsProviderRpiOverlay \

3. 运行时查看动态overlay

查看overlay帮助

cmd overlay

dump android下的overlay

cmd overlay dump [package]

255|console:/ # cmd overlay dump com.android.providers.settings.rpi
com.android.providers.settings.rpi:0 {
  mPackageName...........: com.android.providers.settings.rpi
  mOverlayName...........: null
  mUserId................: 0
  mTargetPackageName.....: com.android.providers.settings
  mTargetOverlayableName.: null
  mBaseCodePath..........: /vendor/overlay/SettingsProviderRpiOverlay.apk
  mState.................: STATE_ENABLED
  mIsEnabled.............: true
  mIsMutable.............: false
  mPriority..............: 2
  mCategory..............: null
  mIsFabricated..........: false
}
com.android.providers.settings.rpi:10 {
  mPackageName...........: com.android.providers.settings.rpi
  mOverlayName...........: null
  mUserId................: 10
  mTargetPackageName.....: com.android.providers.settings
  mTargetOverlayableName.: null
  mBaseCodePath..........: /vendor/overlay/SettingsProviderRpiOverlay.apk
  mState.................: STATE_ENABLED
  mIsEnabled.............: true
  mIsMutable.............: false
  mPriority..............: 2
  mCategory..............: null
  mIsFabricated..........: false
}
IDMAP OF com.android.providers.settings.rpi
Paths:
    target path  : /system/priv-app/SettingsProvider/SettingsProvider.apk
    overlay path : /vendor/overlay/SettingsProviderRpiOverlay.apk
Mapping:
    0x7f02000d -> 0x7f010000 (bool/def_bluetooth_on -> bool/def_bluetooth_on)
    0x7f020010 -> 0x7f010001 (bool/def_device_provisioned -> bool/def_device_provisioned)
    0x7f020019 -> 0x7f010002 (bool/def_lockscreen_disabled -> bool/def_lockscreen_disabled)
    0x7f02002c -> 0x7f010003 (bool/def_stay_on_while_plugged_in -> bool/def_stay_on_while_plugged_in)
    0x7f020032 -> 0x7f010004 (bool/def_user_setup_complete -> bool/def_user_setup_complete)
    0x7f050009 -> 0x7f020000 (integer/def_location_mode -> integer/def_location_mode)
    0x7f050013 -> 0x7f020001 (integer/def_screen_brightness -> integer/def_screen_brightness)

console:/ #

查看android包下的overlay

cmd overlay list [package]

console:/ # cmd overlay list com.android.providers.settings
com.android.providers.settings
[x] com.android.providers.settings.rpi
[ ] com.android.shell:com.android.providers.settings.rpi
[ ] com.android.shell:def_dock_audio_media_enabled
console:/ #

x表示此overlay处于生效中。

enable/disable overlay (配置了isStatic=true的是无法disable的)

cmd overlay disable com.android.providers.settings

cmd overlay enable com.android.providers.settings

Exception occurred while executing 'enable':
java.lang.SecurityException: commit failed

我执行这个命令会抛异常,不知道为什么,有知道的可以告知一下。

disable除指定overlay之外其他的所有overlay

cmd overlay enable-exclusive 

查看overlay的值

cmd overlay lookup

console:/ # cmd overlay lookup com.android.providers.settings com.android.providers.settings:integer/def_screen_brightness
128

可以看到def_screen_brightness已经被改写为128。

即使没有overlay也可以用这个方法查看原生配置的值,调试时很有用。

添加一个overlay

cmd overlay fabricate --target android --name com.android.internal.systemui.navbar.twobutton android:integer/config_navBarInteractionMode 0x010 0x1

  • 10
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android overlay是一种在Android应用程序中实现界面定制化的技术。通过使用overlay,开发者可以在不修改原始应用程序代码的情况下,添加、修改或替换应用程序的布局、样式和资源。在Android中,overlay通常是通过创建一个新的AndroidManifest.xml文件来实现的。\[1\] 在创建AndroidManifest.xml文件时,需要指定overlay的优先级、是否静态以及目标包名。优先级决定了overlay的显示顺序,静态表示overlay在运行时不会被修改,目标包名指定了要进行定制化的应用程序。\[1\] 除了创建AndroidManifest.xml文件,还可以参考一些相关的资料来了解更多关于Android overlay的信息。例如,可以参考http://mmmyddd.github.io/wiki/android/overlay.html和https://developer.sonymobile.com/2014/04/22/sony-contributes-runtime-resource-overlay-framework-to-android-code-example/。\[2\] 在编译后生成的apk中,overlay的路径可以根据不同的方案进行调整。一种常见的路径是vendor/overlay/TestOverlay/TestOverlay.apk,可以通过设置LOCAL_MODULE_PATH来指定路径。\[3\] #### 引用[.reference_title] - *1* *3* [Android Overlay机制](https://blog.csdn.net/weixin_44021334/article/details/130421043)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Android overlay简单总结](https://blog.csdn.net/Dylan_Sen/article/details/78878641)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值