Android 源码之overlay分析
文章目录
- 前言
- 编译方式
- 前提
- 静态Overlay
- res 目录
- 运行时Overlay
- 与SRO的区别
- 配置步骤
- 存在的问题
- RRO注意事项
- 资源ID
- 总结
- 关于源码中的device.mk
前言
Android Overlay是一种资源替换机制,它能在不重新打包apk的情况下,实现资源文件的替换(res目录非assert目录),Overlay又分为静态Overlay(Static Resource Overlay)与运行时Overlay(Runtime Resource Overlay),他有自己的局限性,它无法替换java文件。
Android Override是一种文件替换方式,注意是文件替换,他有自己的局限性,它无法覆盖一个APK中的某一个文件,但是可以直接覆盖APK。
编译方式
编译类型:mmm mm m
source build/envthup.sh
brunch -b -f (override文件打入源码中)
lunch
make
adb sync
framework-res.apk
framework-res__auto_generated_rro_product.apk
adb shell sync 命令:
1,在shell中执行
2,将内存缓冲区中的数据 写入到磁盘
adb sync 命令:
命令意思:同步更新/data/或/system/下的数据
命令用法:adb sync [directory]
如果不指定目录,将同步更新/data/和/system
前提
Overlay需要在源码编译环境中完成
静态Overlay
静态Overlay,简称为SRO,发生在编译时,需要在Android系统源码环境中进行配置。\device\sample\products\backup_overlay.mk
res 目录
目录Directory | 资源类型Resource Types |
---|---|
res/anim/ | XML文件,它们被编译进逐帧动画(frame by frame animation)或补间动画(tweened animation)对象 |
res/drawable/ | .png、.9.png、.jpg文件,它们被编译进以下的Drawable资源子类型中:要获得这种类型的一个资源,可以使用Resource.getDrawable(id) 位图文件 9-patches(可变尺寸的位图)为了获取资源类型,使用mContext.getResources().getDrawable(R.drawable.imageId) |
res/layout/ | 被编译为屏幕布局(或屏幕的一部分)的XML文件。参见布局声明(Declaring Layout) |
res/values/ | 可以被编译成很多种类型的资源的XML文件。 |
res/xml/ | 任意的XML文件,在运行时可以通过调用Resources.getXML()读取。 |
res/raw/ | 直接复制到设备中的任意文件。它们无需编译,添加到你的应用程序编译产生的压缩文件中。要使用这些资源,可以调用Resources.openRawResource(),参数是资源的ID,即R.raw.somefilename。 |
注意: 不像其他的res/文件夹,它可以保存任意数量的文件,这些文件保存了要创建资源的描述,而不是资源本身。XML元素类型控制这些资源应该放在R类的什么地方。
尽管这个文件夹里的文件可以任意命名,不过下面使一些比较典型的文件(文件命名的惯例是将元素类型包含在该名称之中):
array.xml 定义数组colors.xml 定义color drawable和颜色的字符串值(color string values)。使用Resource.getDrawable()和Resources.getColor()分别获得这些资源。dimens.xml 定义尺寸值(dimension value)。使用Resources.getDimension()获得这些资源。strings.xml 定义字符串(string)值。使用Resources.getString()或者Resources.getText()获取这些资源。getText()会保留在UI字符串上应用的丰富的文本样式。styles.xml 定义样式(style)对象。
放在这里的图像资源可能会被aapt工具自动地进行无损压缩优化。比如,一个真彩色但并不需要256色的PNG可能会被转换为一个带调色板的8位PNG。这使得同等质量的图片占用更少的资源。所以我们得意识到这些放在该目录下的二进制图像在生成时可能会发生变化。如果你想读取一个图像位流并转换成一个位图(bitmap),请把图像文件放在res/raw/目录下,这样可以避免被自动优化。
运行时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文件及reference resource 类型的文件,如layout、anim、xml目录中的xml文件。虽然RRO具有自己的AndroidManifest.xml文件,但它却不能替换源项目中的AndroidManifest.xml文件。关于layout目录中的xml文件,SRO是可以替换的。
配置步骤
下面以创建Launcher的RRO为例进行说明
创建一个新项目,包名命名为com.android.launcher.overlay,事实上包名可以随意命名,这样命名可读性高,一看包名就知道是哪个项目的overlay。
编辑overlay项目的AndroidManifest.xml文件,文件内容如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.launcher.overlay"> <overlay android:targetPackage="com.android.launcher" android:priority="1"/> </manifest>
其中,android:targetPackage:需要overlay的项目的包名
android:priority:设置overlay.apk的优先级,值越大,优先级越高,用于存在多个overlay.apk情况下的判断。
替换相对应路径下的res资源
编写mk文件,编译、打包、签名,并将生成的overlay.apk输出到/vendor/overlay目录下,Android 8.0以后 其中签名需要与源项目签名一致,否则不会生效。
存在的问题
把app放到vendor/overlay下面以后,还要activate,默认是disable的
activate有两种方式:
一种是overlay的app的清单文件中,overlay标签写 isStatic=“true”
一种是加系统属性ro.boot.vendor.overlay.theme=overlay的app的包名,分号分割
PS:没有源码环境,或者不懂mk文件,可以通过root手机,直接将我们生成的overlay.apk直接push到/vendor/overlay目录下,来测试RRO机制。
部分厂商可能更改了路径,可通过adb shell pm path xxxx.overlay 查找到路径,前提是手机中已经安装了某个overlay的apk。
RRO注意事项
- 生成的apk需要指定输出到vendor下才会生效
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/overlay
include $(BUILD_PACKAGE) - 由于overlay替换的是资源文件,所以必须调用res目录资源文件
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res - android:priority范围是0-9999,过万就不生效了 (越大优先级越高)
单个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中查找到,并返回。
资源ID
资源文件在打包之后,会在R.java文件中生成一个对应的int类型资源id,这个id遵循以下的规则:
0xppttiiii
其中,
pp:01表示是系统资源,7f表示是应用资源
tt:用于表示资源类型,如string、array、图片资源等
iiii:用于表示相同类型的不同资源
总结
SRO实际上只是利用AAPT重新打包,发生在编译时;RRO,才是overlay机制的关键,其本质是Android系统的动态资源查找机制。
overlay新增一个资源通过add-resource 方式添加
<!-- add for status bar system icon define --><add-resource type="string" name="status_bar_child_mode"/><string translatable="false" name="status_bar_child_mode">child_mode</string>
关于源码中的device.mk
这里有一个overlay的先后问题,比较重要。由高到底
- DEVICE_PACKAGE_OVERLAYS
- PRODUCT_PACKAGE_OVERLAYS–级别最高,也就是优化用PRODUCT_PACKAGE_OVERLAYS中的overlays(高于DEVICE_PACKAGE_OVERLAYS)
- PRODUCT_ENFORCE_RRO_TARGETS
- PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS
在Android O上面 Google增加了一个enforced RRO的方法,可以把之前的build time overlay强制转换成runtime resource overlay.如果overlay的是framework-res的资源包,那麽会自动生成一个file在/vendor/overlay/framework-res__auto_generated_rro.apk.里面会包含overlay的资源。也就是说,对于加了PRODUCT_ENFORCE_RRO_TARGETS的模块,便由SRO变成RRO模式,如果仍然想保持SRO模式,就需要使用到PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS变量。
具体原因见此文章
另外,出于安全性考虑,谷歌公司在Android 8.0版本后,不仅要求Overlay apk 和Target apk这两个apk中的签名–致,还需要在源项目Targetapk中的AndroidManifest. xml文件中声明具有android.permission. CHANGE_ OVERLAY_ PACKAGES 的权限。
代码中存在的RRO.apk
Android 源码之overlay分析相关推荐
- 从Android源码的角度分析Binder机制
IPC 为了弄懂IPC的来龙去脉,我将从以下三个方面为大家来讲解,希望对大家理解IPC会有帮助 什么是IPC IPC是Inter Process Communication的缩写,其意思就是进程间的通 ...
- Android 源码 installPackage 流程分析
installPackage 安装流程最终会调用 PackageManagerService 对应方法,当然是使用 binder 机制得以实现跨进程通信. 先来看看 installPackage 流程 ...
- Android 源码 PackageManagerService 启动流程分析
<Android 源码 installPackage 流程分析>一节着重分析了 apk 安装流程,接下来我们分析 PackageManagerService 启动时都做了些什么? 执行 P ...
- 【Android源码】Activity如何加载布局
我们都知道在Activity中通过setContentView(layoutId)来加载布局文件,使我们的布局文件能够显示在手机上,那么系统是如何将我们的布局文件加载到界面上的呢? setConten ...
- Android 源码 输入系统之 InputReader
InputReaderThread 线程负责读取事件.InputReaderThread 启动后会执行 threadLoop 函数.threadLoop 函数返回 true,InputReaderTh ...
- android源码分析
01_Android系统概述 02_Android系统的开发综述 03_Android的Linux内核与驱动程序 04_Android的底层库和程序 05_Android的JAVA虚拟机和JAVA环境 ...
- Android 源码分析
查看源码版本号: build\core\version_defaults.mk //搜索该文件中的 PLATFORM_VERSION值 frameworks 目录 (核心框架--java及C++语言) ...
- Android源码分析-全面理解Context
前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...
- Android源码分析--MediaServer源码分析(二)
在上一篇博客中Android源码分析–MediaServer源码分析(一),我们知道了ProcessState和defaultServiceManager,在分析源码的过程中,我们被Android的B ...
最新文章
- 转:Oracle 应用服务器 MapViewer 10.1.2截图
- 关于分组序号在MySQL中的实现
- 『Windows Tips』Windows 自带屏幕截图的使用
- 一种不通过UI给C4C自定义BO创建测试数据的方式
- 优秀技术人的管理陷阱
- NLP太难学了!?吃透NLP的方法来拿走
- 从几个版本的memcpy的测速过程学习一点底层的东西
- 容器编排技术 -- Pod 安全策略
- 一条语句引发的思考:装箱和拆箱,空指针的类型转换
- mysql.exe怎么全屏_监控怎么调为全屏
- mock.js那点事(上)
- 药品信息管理系统mysql_药品信息管理系统数据库部分代码
- matlab晶格图,科学网-MATLAB软件绘制一维双原子晶格的格波色散曲线-李金磊的博文...
- 小程序的视频代码示例
- PushService开发分享
- 高登数学,线性代数问题的数值解(SciPy第三方库,近似解)
- 百度智能云服务器BCC实例在线配置变更
- SpringBoot使用easyexcel打印数据
- 计算机怎么知道乘法优先,计算器算个明白.doc
- STM32F103时钟系统讲解(精)