apk 瘦身;如何缩小体积呢?这篇文章来教你
apk 瘦身之旅
我们完成一个 app 后,都需要生成一个 apk,然后上线,而 apk 的大小也一定程度的影响了用户是否愿意下载你的这个 app,所以也就有了 apk 瘦身这门艺术。
目录
apk 的结构
图片压缩
导入矢量图
适配问题
Tint 着色器
动态库移除
so 库的相关知识点
ABI
结束语
apk 的结构
既然要对一个 apk 瘦身,首先我们就得知道 apk 格式的文件内容。实际上一个 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 apk 文件就是一个 zip 包,我们只需要将后缀改为 zip,然后进行解压就可以看到里面的内容了。下面我们来看下它里面的文件以及作用:
apk 包含以下目录:
assets/
: 包含了应用的资源,这些资源能够通过 AssetManager 对象获得。lib/
: 包含了针对处理器层面的被编译的代码。这个目录针对每个平台类型都有一个子目录,比如 armeabi, armeabi-v7a, arm64-v8a, x86, x86_64 和 mips。res/
: 包含了没被编译到 resources.arsc 的资源。META-INF/
: 包含 CERT.SF 和 CERT.RSA 签名文件,也包含了 MANIFEST.MF 文件。(译注:校验这个 APK 是否被人改动过)
apk 包含以下文件:
classes.dex
: 包含了能被 Dalvik/Art 虚拟机理解的 dex 文件格式的类。resources.arsc
: 包含了被编译的资源。该文件包含了 res/values 目录的所有配置的 xml 内容。打包工具将 xml 内容编译成二进制形式并压缩。这些内容包含了语言字符串和 styles,还包含了那些内容虽然不直接存储在 resources.arsc 文件中,但是给定了该内容的路径,比如布局文件和图片。所以又叫 资源映射表AndroidManifest.xml
: 包含了主要的 Android 配置文件。这个文件列出了应用名称、版本、访问权限、引用的库文件。该文件使用二进制 xml 格式存储。(译注:该文件还能看到应用的 minSdkVersion, targetSdkVersion 等信息)
好的,现在我们已经知道 apk 到底是个什么东东了,接下来我们开始一步步对这些内容进行瘦身处理。
图片压缩
我们都知道,一个 apk 会使用大量的图片,如果图片这块能够压缩下,那效果还是非常可观的。
如下图,我们在项目中经常会用到这样的套图。
明明只是一种图片,而我们却因为大小和颜色,需要这样的一组,显然很占大小,那有没有什么方式优化下呢?
答案是有的。
谷歌的 AS 为我们提供了一个名为 Vector Asset Studio 的工具,可以帮助我们添加内置 Material 图标以及将本地的 SVG(Scalable Vector Graphics 可缩放矢量图)等格式作为矢量图资源导入到项目中,会在 drawable 目录下生成一个根节点为 vector 的 xml 文件,而且矢量图的大小也更小,是不是非常棒啊!那下面我们来看看怎么实现的。
导入矢量图
首先我们在 AS 中运行 Vector Asset Studio,步骤是:右键点击你工程中的 res 文件夹,然后选择 New --> Vector Asset,此时会弹出下面对话框,选择图中标记的对应操作即可导入内置 Material 图标或者 SVG 矢量图。
但是上面这种方式只能一张张导入图片,显然很麻烦。那有没有更好的方式了?实际上我们之所以要用这个工具导入 svg 图片,而不是直接将 svg 图片复制到 drawable 中,是因为安卓不支持 svg,需要工具转换下,所以我们可以使用 svg2vector 这个第三方库进行批量转换,然后直接复制到 drawable 中即可,转换命令如下:
java -jar svg2vector-cli-1.0.0.jar -d . -o a -h 20 -w 20
-d 指定 svg 文件所在目录-o 输出 android vector 图像目录-h 设置转换后 svg 的高-w 设置转换后 svg 的宽
适配问题
因为矢量图是在 Android 5.0(API21)才开始支持的,所以这个地方我们还需要适配下。如果不适配,你的最小 minSdkVersion 版本又小于 21,则会自动在每个 drawable 目录下生成对应的 png 图片,反而会使 apk 包变大,所以这里一定要注意了。我们有下面两种方式进行适配:
方式一:生成 png 格式的图片
这种方式是在 drawable 文件中生成对应的 png,不过我们可以指定只生成哪几个。例如如下配置
我们可以在项目的 build.gradle 中进行如下配置,即可在指定的 drawable 文件中生成对应的 png 格式图片。
方式二:支持库
还一种方式就是使用支持库,支持库的版本需要 23.2 或者更高,也是在项目的 build.gradle 中进行配置,如下:
这种适配方式使用图片的时候,需要用 app:srcCompat
属性,而不是 android:src
,如下:
通过这个方式只是解决了不同大小需要多张图片的问题,但是还需要有不同颜色的图片。这个我们怎么处理呢?不要急,这个问题谷歌工程师也为我们准备了一个工具,它就是 Tint 着色器。
Tint 着色器
一般我们矢量图都是使用黑色,然后由 Tint 着色器去修改颜色,直接在 xml 中使用即可,如下:
在 java 代码中,我们可以通过 DrawableCompat 去设置,如下:
那如果想要实现按键效果,通过 Tint 也能实现吗?答案是可以的。
首先我们需要创建两个选择器,一个是 drawable 选择器,一个是 color 选择器,如下:
评论