本章要介绍的运行时Overlay(RuntimeResourceOverlay)

Android Runtime Resource Overlay 简介】并不冲突,

只是在新的Android O版本,Google对于RR0机制的安全性进行了加强,后续有详细介绍。


首先系统编译过程中一般会将packages/apps目录下的源码项目通过AAPT打包成APK,存放至system/app或者system/priv-app目录下,最后连同其他资源打包得到系统镜像,当然也可以将APK直接打包到系统镜像。

静态Overlay 
静态Overlay,简称为SRO,发生在编译时,需要在Android系统源码环境中进行配置。


配置步骤:

1.修改产品(高通msm8996对于framework层字串)的mk文件,添加如下代码:

t88909aa1/ap/android/device/qcom/NameDateSizecommon/H24-三月-20184 KiBmsm8909/H31-三月-20184 KiBmsm8909_512go/H10-三月-20184 KiBmsm8909go/H24-三月-20184 KiBmsm8996/H24-三月-20184 KiBsepolicy/H06-一月-20184 KiBt88909aa1/ap/android/device/qcom/msm8996/H A Dmsm8996.mk73 $(call inherit-product, device/qcom/common/common64.mk)t88909aa1/ap/android/device/qcom/common/H A Dcommon.mk5 # device-vendor.mk first to make sure QC specific files gets installed.$(call inherit-product-if-exists, $(QCPATH)/common/config/device-vendor.mk)H A Dcommon64.mk5 # device-vendor.mk first to make sure QC specific files gets installed.$(call inherit-product-if-exists, $(QCPATH)/common/config/device-vendor.mk)t88909aa1/ap/android/vendor/qcom/proprietary/common/config/device-vendor.mk$(call inherit-product-if-exists, vendor/qcom/proprietary/qrdplus/Extension/products.mk)$(call inherit-product-if-exists, vendor/qcom/proprietary/qrdplus/Extension/products.mk)t88909aa1/ap/android/vendor/qcom/proprietary/qrdplus/Extension/ PRODUCT_PACKAGE_OVERLAYS += vendor/qcom/proprietary/qrdplus/Extension/apps/BatterySaver/overlay实际修改的overlay文件:t88909aa1/ap/android/vendor/qcom/proprietary/qrdplus/Extension/apps/BatterySaver/overlay/frameworks/base/core/res/res/values/strings.xml
2.在overlays目录下添加对应产品的overlay项目,overlay项目实际上就是源项目剔除代码和替换资源后的项目,注意包名路径需要与源项目保持一致。

SRO

原理 

实际上,SRO的实现很简单,只是在通过AAPT打包成APK时,通过-S命令多增加了一个资源目录(overlay目录)而已,我们平时打包APK只是通过AAPT -S指定了一个资源目录,而Overlay又额外增加了一个资源目录而已。
AAPT -S命令可以指定多个资源目录,overlay的资源将替换原res中的重名文件。可见SRO在编译成APK时已经完成。


运行时Overlay 

运行时Overlay,简称RRO,顾名思义,该机制的资源替换发生在运行时。

与SRO的区别 

RRO能直接定制替换第三方APK的资源,而不需要其源码。SRO如上节所述,则需要对应APK的源码才能完成,一般而言,第三方是不会提供项目源码的。

RRO的编译结果会得到一个xxx_overlay.apk,加上原项目的apk,总共会有2个apk,而SRO最终只会得到一个已经完成资源替换的apk。得到的overlay.apk可以视为一个正常的apk,因为它能被安装,含有自己的AndroidManifest.xml文件,当然正常下,overlay.apk是不含有执行代码的。

RRO不能替换AndroidManifest.xml文件及layout目录中的xml文件。虽然RRO具有自己的AndroidManifest.xml文件,但它却不能替换源项目中的AndroidManifest.xml文件。关于layout目录中的xml文件,SRO是可以替换的。


配置如下:

下面以创建WuiDemo的RRO为例进行说明:

创建一个新项目,包名命名为

com.overlay.wuidemo
,事实上包名可以随意命名,这样命名可读性高,一看包名就知道是哪个项目的overlay。

编辑overlay项目的AndroidManifest.xml文件,文件内容如下:

<?xml version="1.0" encoding="utf-8"?>    


其中,
android:targetPackage:需要overlay的项目的包名
android:priority:设置overlay.apk的优先级,值越大,优先级越高,用于存在多个overlay.apk情况下的判断。

替换相应的res资源

编写mk文件,编译、打包、签名,并将生成的overlay.apk输出到/vendor/overlay目录下,其中签名需要与源项目签名一致,否则不会生效。

PS:没有源码环境,或者不懂mk文件,可以通过root手机,直接将我们生成的overlay.apk直接push到/vendor/overlay目录下,来测试RRO机制。
部分厂商可能更改了路径,可通过adb shell pm path xxxx.overlay 查找到路径,前提是手机中已经安装了某个overlay的apk。


至此,我们需要额外关注就是Android O在RRO变化:

1.安全性提高,需要的不仅仅时OverLay同Target 两个Apk签名一致,还需要在Target Apk声明具有android.permission.CHANGE_OVERLAY_PACKAGES。

    

分析:

frameworks/base/services/core/java/com/android/server/om/OverlayManagerService.javaprivate void enforceChangeOverlayPackagesPermission(@NonNull final String message) {            getContext().enforceCallingOrSelfPermission(                    android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, message);        }
代码中检查权限的举动

2.配置规范行

Android O上面对于RRO,Google专门为其提供一个服务【OverlayManagerService】,如下:

t88909aa1/ap/android/frameworks/base/services/java/com/android/server/H A DSystemServer.java91 import com.android.server.om.OverlayManagerService;649 mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));t88909aa1/ap/android/frameworks/base/core/java/android/content/om/OverlayInfo.java33 * com.android.server.om.OverlayManagerService} should never have thist88909aa1/ap/android/frameworks/base/services/core/java/com/android/server/om/IdmapManager.javaH A D28-十二月-20174.4 KiBOverlayManagerService.javaH A D28-十二月-201737.3 KiBOverlayManagerServiceImpl.javaH A D28-十二月-201723.5 KiBOverlayManagerSettings.javaH A D28-十二月-201719.6 KiBOverlayManagerShellCommand.javaH A D28-十二月-20177.1 KiB    /t88909aa1/ap/android/frameworks/base/services/core/java/com/android/server/pm/H A DPackageManagerService.java846 // OverlayManagerService will update each of them with a correct gid from its

在【frameworks/base/services/core/java/com/android/server/om/OverlayManagerService.java】306行我们可以看到

frameworks/base/services/core/java/com/android/server/om/OverlayManagerService.javaprivate static final String DEFAULT_OVERLAYS_PROP = "ro.boot.vendor.overlay.theme";private static Set getDefaultOverlayPackages() {307        final String str = SystemProperties.get(DEFAULT_OVERLAYS_PROP);308        if (TextUtils.isEmpty(str)) {309            return Collections.emptySet();310        }311312        final ArraySet defaultPackages = new ArraySet<>();313        for (String packageName : str.split(";")) {314            if (!TextUtils.isEmpty(packageName)) {315                defaultPackages.add(packageName);316            }317        }318        return defaultPackages;319    }

此处还需要配置overlay包名,多个overlay应用需要以;分隔。

故我们时需要配置【ro.boot.vendor.overlay.theme】属性的。


原理 

以我们常见的图片资源访问为例,当我们在应用层调用getDrawable方法的时候,会调用系统的getResource方法,该方法会根据资源id及设备配置信息(语言、像素密度等)来查找并返回合适的图片资源。此处,我们只关注根据id来选择资源。

如果id表明是系统资源,那么就会去framework-res.apk中查找并返回资源,一般位于/vendor/framework目录下,可root手机查看;如果是应用资源则在overlay和app中查找并返回。


RRO

个overlay包 

当对应项目只有一个overlay包时,那么查找资源时,会先从overlay.apk中进行查找,查找成功直接返回,反之则从app中查找。

多个overlay包 

当对应项目具有多个overlay包时,会按照overlay包的优先级从高到底依次进行查找,如果overlay包都查找失败,才会到app中进行查找。
以访问R.drawable.ic_01为例,会先从overlay1包先查找,因为其优先级最高,查找到则直接返回。
如果访问R.drawable.ic_02,先从overlay1查找,查找失败,接着从overlay2中查找,查找到直接返回。
如果访问R.drawable.ic_03,依次从overlay1,overlay2中查找,查找失败,最后会从app中查找到,并返回。


ps:

a.OverLay同Target Apk需要签名一致

b.Target Apk需要申请允许RRO overlay权限

c.OverLay同Target Apk必须保持统一的资源ID,系统或应用或其他自定义的资源ID

【资源ID】 

我们知道资源文件在打包之后,会在R.java文件中生成一个对应的int类型资源id,这个id遵循以下的规则:
0xppttiiii
其中,
pp:01表示是系统资源,7f表示是应用资源
tt:用于表示资源类型,如string、array、图片资源等
iiii:用于表示相同类型的不同资源


总结 

SRO实际上只是利用AAPT重新打包,发生在编译时;RRO,才是overlay机制的关键,其本质是Android系统的动态资源查找机制。

实际运用当中,Overlay机制一般用于手机厂商为不同运营商做客制化定制,或者做主题换肤;一般,第三方应用是无法享受该机制的,除非与手机厂商合作,不过应用层现在也有了换肤框架Android-Skin-Loader,其本质也是利用Android的资源查找机制。


其他补充 :https://blog.csdn.net/wh_19910525/article/details/39254815#comments




https://blog.csdn.net/Dylan_Sen/article/details/78878641 Android overlay简单总结




https://blog.csdn.net/wh_19910525/article/details/39254815  Android平台Overlay机制



更多相关文章

  1. android java file 清理垃圾获取文件大小 删除文件等操作
  2. Android(安卓)Studio--window下载安装及helloworld
  3. android 由资源名称获得ID的方法
  4. Android(安卓)本地文件、文件夹操作
  5. Android(安卓)ADB命令大全(通过ADB命令查看wifi密码、MAC地址、
  6. Android深入浅出系列课程---Lesson15LLY110602_Dalvik虚拟机概述
  7. Mac系统下对Android(安卓)apk进行反编译
  8. Android(安卓)Studio开发之JNI ---- 加载调用第三方so库
  9. 安卓开发过程中遇到的问题总结及解决方法

随机推荐

  1. Android:可移动悬浮框
  2. Android(安卓)监控应用删除,并提示处理
  3. Android实现Alphabet ListView
  4. Android(安卓)Studio 使用中 遇到的那些
  5. 监听TextView的变动
  6. android制作一个简单登入界面的部分代码
  7. Android自定义Toast 解决关闭通知 Toast
  8. Android(安卓)TabSwitcher自定义控件
  9. Android(安卓)TextView中android:textIsS
  10. Flutter 与 Android(安卓)相互调用、传递