Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

前介

一个 Apk 主要分为 resdexMETA-INFAndroidManifest.xmlresources.arsc 组成(对应文件作用看下方表格)。

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

从图片可以看到一个项目的 res 占很大一部分内存,其次就是 dex 文件。所以优化 Apk 的体积就应该从 resdex 出发。
Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

昵称 介绍
res Apk 资源,代码中对应的 res 目录下的所有通过 AAPT 编译的产物。
dex 所有的 Class 文件的归宿
META-INF 报错通过 V1 签名的签名信息
AndroidManifest.xml 通过 AAPT 优化编译的清单文件
resources.arsc 通过 AAPT 编译资源生成的产物,主要存放资源 IDR 类生成的 ID )和 res 目录下的资源文件对应关系

定位目标

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

前面都是一堆准备工作,我们来明确目标。最终要完成在 APK 构建过程中,将 res 目录下所有的图片进行 去重压缩处理混淆

寻找合适的Task

确定了目标后,我们就知道优化的目标在 Apkres 目录下所有的资源文件,由于存在对 res 目录的文件进行 (混淆) 丶 (去重) 的情况,在修改的同时还需要修改 resources.arsc 文件。因为前面讲了,这个文件中存着一份 ID 和 资源的映射关系。

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

这里大家是不是就能衍生出换肤的难点在哪了吧?要保证新生成的皮肤 resources.arscID 要和宿主的 ID 保持一致。这样代码中才能正确的通过 ID 找资源,其实 R 也是 AAPT 插件生成的哦。学完这篇我相信大家也能做一款属于自己的换肤插件。

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

接下来思路就清晰了。我的第一想法是在生成 resources.arsc 前,优化 res 目录下面所有的图片。这样就规避掉了
修改 resources.arsc 的难点。

通过第一章代码我还真找到了一个 mergeDebugResourcesTask 它的作用就是合并资源,包含依赖的资源(如何找呢?通过我上一篇分享的文章,看每个 Task 的输入路径)。但是回头一想,这样就不能做去重复的功能了,因为我如果删除重复的资源,代码引用并不知道啊!(因为我的删除重复资源是相同文件,并不是简单昵称相同)。

到这里,我们分析结束,只能在生成 resources.arsc 之后做优化操作,并修改 resources.arsc 文件了。哪 resources.arsc 是多久生成的呢?我们来看下面的一张图。

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

AAPT 来打包 res 资源文件,生成 R.javaresources.arscres文件。我们只需有找到一个执行 AAPTTask 在这个 Task 之后做操作。

其实我当时中间有另外一种想法,能不能自己改造一个 aapt 呢?查阅资料思路是可行的,但是过于复杂和兼容性不强(主要需要改 C 代码,我不会),有兴趣可以参考

接下来我们应该找一个执行 AAPTTASK,接着用我前面讲的输出所有 Task 的输入和输出路径,寻找产物有 resources.arscTask

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

我在 build 目录中找了半天 resources.arsc 文件,但是死活找不到。

最后发现了一个 processDebugResourcesTask

  1. 调用 aapt 生成项目和所有 aar 依赖的 R.java , 输出到 app/build/generated/source/r/debug 目录
  2. 生成资源索引文件 app/build/intermediates/res/resources-debug.ap_
  3. 把符号表输出到 app/build/intermediates/symbols/debug/R.txt

这个 Task 的产物是 resources-debug.ap_ (就是个 zip 文件)解压下就可以所有的数据了。

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

终于看到 resources.arsc 并且还附带了 res 中所有的资源了。

Andorid资源瘦身去重丶图片压缩丶混淆插件(3)

没事干你整个压缩包干嘛呀,害的我找了好久。

最后只需要在 processDebugResources Task 之后,解压 resources-debug.ap_ 文件,遍历 res 下所有的图片进行去重丶压缩丶混淆丶修改 resources.arsc ,从新压缩改造内容,替换 resources-debug.ap_ 文件即可。

源代码

QOptimize 插件是一款,在 Apk 编译期间对 Apk 进行体积优化的一款插件。

git地址

博客地址