【Android】【学习笔记】运行时资源替换-Runtime Resource Overlay 学习实践

初入职场的新的软件攻城狮,每天任务除了基础的技能学习,包括C++、Java、Andorid、算法等,就是跟着工作导师布置的任务,学习一些实用的小技能。工作导师作为资深程序猿,闷骚是一大属性,除了自己要能主动勾搭,还有就是要学会提高自觉性了。这天工作导师冷不丁发来一个链接,主要内容就是本次需要详细记录的Android运行时资源替换:http://blog.csdn.net/azhengye/article/details/49050631。
本次实践流程基于Linux Ubuntu系统,因为需要在Android源码环境下编译,所以和Windows系统没啥关系,不过后文提到的反编译的内容在Windows环境下操作过程大同小异。技术原理与应用在此就不做讨论,提供的参考文章也会有提到。

反编译相关apk文件

为了玩反编译玩得开心,我在网上下载了:计算器简约版.apk微信.apk两个安装包,都于10月12日为最新版本,将计算器简约版作为本次运行时资源替换实践操作的对象。因为直接对apk文件包进行解压是无法得到它的原始资源文件的,解压目录中存在的资源文件在打包时都被编译过,所以我们直接打开看到的都不是明文,这里就需要我们进行资源文件的反编译,相关代码反编译的内容将会在最后给出一些参考文章。
对apk文件包的资源文件进行反编译,我用到了一个工具apktool,下载地址:https://ibotpeaches.github.io/Apktool/install/
下载界面截图如下:
【Android】【学习笔记】运行时资源替换-Runtime Resource Overlay 学习实践_第1张图片
根据提示内容,我们需要右键点击wrapper script将链接另存为apktool ;点击 find newest here 下载jar包并将其重命名为apktool.jar ;然后我把 apktoolapktool.jar 放到新建的 apktool 文件夹下,这里放到自己的工作目录即可,最后执行 chmod 命令为其赋予权限,我赋予了权限755,或许存在考虑不周的情况。
准备工作完毕,下面开始反编译资源文件,打开终端,cd进入到 apktool 文件夹目录下,执行命令:apktool d apk存放位置/xxx.apk
比如我的话就执行: apktool d ../计算器简约版.apk
执行完毕就会在 apktool 文件夹下生成名为 计算器简约版 的文件夹。同理执行: apltool d ../weixin_1100.apk ,结果如图:
【Android】【学习笔记】运行时资源替换-Runtime Resource Overlay 学习实践_第2张图片
注意:如果遇到Exception in thread “main” brut.androlib.AndrolibException: Could not decode arsc file 类似的错误提示,是因为 apktool 工具版本不是最新的导致的,下载最新版就好了。
至此,我们就可以在 计算器简约版 文件夹中查看自己需要替换的文件的信息了。我的替换目标是 res/drawable/ic_launcher.pngres/values-zh-rCN/strings.xml 配置文件中的app_name属性。反编译微信我其实就是想拿它的 ic_icon 图片,其它部分我再后面留着自己玩玩,毕竟替换资源替换一个大家都比较熟悉的就很能说明问题了。

新建Overlay工程

首先在Andoird源码目录/packages/apps下新建自己的Overlay文件夹,我的是miniCalcOverlay文件夹,接着在文件夹下创建自己对应目标的替换文件,Android.mk 和 AndroidManifest.xml文件。比如我创建的文件目录:
【Android】【学习笔记】运行时资源替换-Runtime Resource Overlay 学习实践_第3张图片
其中,res 文件夹下的内容同我的替换目标的内容一致。
资源文件/res/values-zh-rCN/strings.xml:



<resources>

    <string name="app_name">计算器Overlaystring>

resources>

这里需要替换的就是app_name的显示内容,这个名字必须和待替换的资源名(app_name)相同,即和计算器简约版项目中res/values-zh-rCN/strings.xml中的对应的资源名字(app_name)相同。对,我只是给名字后面加上了Overlay表示。
配置文件AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.liyao.miniCalc" >
    <overlay
        android:priority="1"
        android:targetPackage="com.mini.calc" />
manifest>

这里只需要注意overlay标签中priority的值是针对一个目标apk的资源可以被多个overlay.apk更改而设置的一个优先级,值越大优先级越高;targetPackage的值一定是待替换的应用的包名,可以在计算器简约版项目中AndroidManifest.xml配置文件头的package找到。
编写编译脚本Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)  
LOCAL_MODULE_TAGS := optional
#include files in src directory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
#include files in res diretory
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res  
LOCAL_SDK_VERSION = current
#the name of target apk 
LOCAL_PACKAGE_NAME := MiniCalcOverlay
include $(BUILD_PACKAGE)

模板就和我的差不多,需要详细了解makefile编译脚本也有得查了。

编译Overlay工程

编写完毕以后,接下来对项目进行单独编译即可。
我的编译过程:
进入Android源码根目录,依次执行命令配置环境和编译:

source build/envsetup.sh 
lunch

lunch后选择对应版本

cd packages/apps/miniCalcOverlay

进入工程目录下执行单独编译命令mm

mm

也可以直接在源码根目录下使用 make 后跟项目路径进行单独编译,只不过这会将Android.mk文件依赖的内容重新编译,速度更慢一点。
这里写图片描述
编译成功后可在输出目录下找到对应的apk文件,我的是在out/target/product/{安卓系统项目名称}/system/app/MiniCalcOverlay下。

验证

由于Android运行时资源替换是在系统层做的,Android出于安全考虑,要想RRO的apk生效必须将生成的overlay apk放到/system/vendor/overlay目录下。
通过adb连接手机与pc,进入/system/vendor/overlay:

adb shell
cd /system/vendor/overlay

如果没有overlay目录则先使用adb remount命令,然后再新建overlay目录:

adb root
adb remount

【Android】【学习笔记】运行时资源替换-Runtime Resource Overlay 学习实践_第4张图片
然后使用adb push命令将生成的overlay apk推送到手机的/system/vendor/overlay目录下:

adb push {Overlay.apk的路径} /system/vendor/overlay

替换后重启手机,替换结果:
【Android】【学习笔记】运行时资源替换-Runtime Resource Overlay 学习实践_第5张图片

参考内容:
http://blog.csdn.net/azhengye/article/details/49050631
http://blog.csdn.net/whurs/article/details/53239785
http://blog.csdn.net/guolin_blog/article/details/49738023/
http://blog.csdn.net/vipzjyno1/article/details/21039349/

你可能感兴趣的:(Android)