Android开发之APK瘦身之法

Android 开发后,apk的大小往往会影响到用户的下载体验。开发人员本着追求极致的精神,apk瘦身是不得不做的工作。

先分析一下APK是由哪些元素构成的。
Android Studio 2.2 之后的版本,可直接能分析APK的大小,双击打开就能看到那些占用APK比例大,方法数等。如下图所示:
这里写图片描述

APK包结构如下:
1. lib/:包含特定于处理器软件层的编译代码。该目录包含了每种平台的子目录,像armeabi,armeabi-v7a, arm64-v8a,x86,x86_64,和mips。大多数情况下我们可以只用一种armeabi-v7a,后面会讲到原因。
2. assets/:包含应用可以使用AssetManager对象检索的应用资源。
3. res/:包含未编译到的资源 resources.arsc,主要有图片资源文件。
4. META-INF/:包含CERT.SF和 CERT.RSA签名文件以及MANIFEST.MF 清单文件。
5. resources.arsc:包含已编译的资源。该文件包含res/values/ 文件夹所有配置中的XML内容。打包工具提取此XML内容,将其编译为二进制格式,并将内容归档。此内容包括语言字符串和样式,以及直接包含在resources.arsc文件中的内容路径 ,例如布局文件和图像。
6. classes.dex:包含以Dalvik / ART虚拟机可理解的DEX文件格式编译的类。
7. AndroidManifest.xml:包含核心Android清单文件。该文件列出应用程序的名称,版本,访问权限和引用的库文件。该文件使用Android的二进制XML格式。
分析后 于是针对做分析优化。
下面总结一下实际开发中用到的一些瘦身方法:

1. 图片资源压缩


手机端的图片这个很关键,得考虑实际的渲染效果,设计人员设计时图片分辨率不能太高,高了也没用。在项目中图片压缩后再使用。

图片压缩推荐
https://tinypng.com/
使用后图片效果几乎没有任何影响,图片体积却大大减小。

2. 放弃一些不需要支持的分辨率


我们知道Android是支持多分辨率的,提供了多套图片适配的机制,我们根据不同尺寸的屏幕来放入多套的图片,比如ldpi、mdpi、hdpi、xhdpi等。但是实际上有些图片你可能是不需要放置的。

对于ldpi,系统会自动的将hdpi的图片缩放到达到目的,所以你就不需要把ldpi的图片拷贝到你的res文件夹下了
有些分辨率的图片你可能是用不到的,比如ldpi和xxxhdpi。前者的手机目前很少了,而后者是针对2k屏幕的,目前还没有普及开。所以对于这点,你可以考虑下是否需要放入这两套图片资源.
在打包时进行选择性加入想要的字符、图片资源。

defaultConfig {

    resConfigs "zh"
    resConfigs "hdpi", "xhdpi", "xxhdpi"
}

defaultConfig提供了resConfig这个flavor来指定打包出只打包某些资源,比如字串、图片等等
3.清除无用的代码和资源文件


code shrinking需要结合ProGuard使用,添加minifyEnabled true在你的build.gradle文件中。

那么我们怎么知道每一次build,删除了和未删除那些资源和代码呢,ProGuard会输出以下文件在/build/outputs/mapping/release/:

dump.txt
描述.apk文件中所有类文件间的内部结构
mapping.txt
列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。
seeds.txt
列出了未被混淆的类和成员
usage.txt
列出了从.apk中删除的代码
resources.txt
列出resource被保留的资源

4.清除无用的代码和资源文件*

开发中可能由于需求更改频繁,堆积了很多冗余的代码,成为僵死代码,打包时记得及时清理。

清除代码:
在Android Studio中打开“Analyze” 然后选择”Inspect Code…”,范围选择整个项目,然后点击”OK”

这里写图片描述


清除资源:
这里写图片描述

5.打包时压缩资源文件


微信中的资源混淆工具主要为了混淆资源ID长度(例如res/drawable/icon.png,png变成混淆为r/s/a.png),同时利用7z深度压缩、对png的存储方式做了改变占用内存更小,大大减少了安装包体积

具体源码与使用方法详细在github中:

https://github.com/shwenzhang/AndResGuard

6.用代码实现图片效果

开发人员在开发中,针对图片和一些动画效果的实现中,尽量用代码来实现。
比如带有规则的图片的按钮、圆形。如按钮的背景、纯色背景都是可以用shape来实现,开发中能实现的尽量不麻烦UI。

小结:

  • 用shape代替背景图
  • 用RotateDrawable代替仅仅是方向不同的“内容相同”的图片
    (如RotateDrawable实现左右剪头的翻转,省去一个箭头的图片大小)
  • 用layer-list来制作多层图片从而达到复用
  • 使用属性动画而不是多图片连续播放的帧动画
  • 使用VectorDrawable和SVG图片来替换原有图片
  • 使用SVG不用考虑屏幕适配问题,体积非常小。
  • 使用jpg格式图片
    如果对于非透明的大图,jpg将会比png的大小有显著的优势,虽然不是绝对的,但是通常会减小到一半都不止。
    在启动页,活动页等之类的大图展示区采用jpg将是非常明智的选择。

7.使用多版本的APK

Multiple APK Support是一个在Google Play,可以发布不同的应用程序,分别针对不同的设备配置特征。每个APK是一个完整的、独立的应用程序版本,但他们分享在Google Play相同的应用程序清单,必须共享相同的包名和与签名。Google Play 会自动给你匹配相应的APK,这样我们的APK 就可以是分不同版本构建需要资源文件,从而减小APK的大小。

通过发布有多个APK,我们可以:

  • 支持不同OpenGL的APK
  • 支持不同的屏幕尺寸和密度的APK
  • 支持不同的设备功能的APK
  • 支持不同的平台版本的APK
  • 支持不同的CPU架构,每个apk(如ARM、x86,MIPS等)的APK

更多相关信息请参考https://developer.android.com/google/play/publishing/multiple-apks.html#Concepts

目前我们基于这个方案做了不同屏幕的APK。

在cpu的架构支持上,一般abi设置为armv7a-64 就可以正式打包就可以了,其他如x86,这个一般在模拟器上测试时debug使用,其他的架构就更小众了,可以 直接忽略。这一个设置很重要,尤其是引入第三方库时,如果每个都支持其他cpu的架构,这个apk体积一下就上去了。 另外,引入第三方库也得注意,根据需求做适当的抽取,不要duang的一下全部引入。

defaultConfig {

    ndk {
        //设置支持的SO库架构
        abiFilters 'armeabi-v7a', 'armeabi' //, 'x86',  'x86_64', 'arm64-v8a'
    }
}

8.资源动态加载


我们可以在项目中使用资源动态加载形式,例如:表情,语言,离线库等资源动态加载,减小APK的大小。

9.支持插件化


未来对于一些独立业务模块,可以做成插件化动态加载,用户需要使用时,只需下载少部分插件。

10.使用ReDex优化


ReDex是Facebook开源一个减小安卓app大小以提高性能的工具,内嵌以及清除僵尸代码这样的优化来减小字节码,主要是对Dex进行了优化,能让APK
运行更快,不过需要多测试是否会崩溃。

教程很简单具体更详细的内容请参考:
https://code.facebook.com/posts/998080480282805/open-sourcing-redex-making-android-apps-smaller-and-faster/

github地址:
https://github.com/facebook/redex.git

总结:

  1. 脚本中开启资源混淆和资源压缩

  2. 用7zip代替zip

  3. gradle脚本中开启代码混淆优化和无用资源删除

  4. 用更小的图,使用压缩工具压缩图片大小

  5. 去除无用的资源,语言,本地so库,二方三方库和分辨率

  6. 用更小的库

  7. 尝试将android support库彻底踢出你的项目

  8. 定期清理代码

  9. 尝试用H5编写界面,图片云端获取

  10. 尝试插件化业务模块

  11. 寻找到zip文件夹中所有用STORE形式存储的文件(不限于raw目录下),尝试压缩,以及替代方案加载这些资源

  12. 尝试webp的图片加载方案,寻求突破

最后,继续学习和尝试新的优化方案

先总结这些,后期完善。如有不对之处,欢迎指出。

参考资料:
1.https://blog.csdn.net/vfush/article/details/52266843#利用andresguard资源压缩打包工具
2.https://blog.csdn.net/offbye/article/details/50834617

3.https://yq.aliyun.com/articles/57284?&utm_source=qq(阿里)

4.https://mp.weixin.qq.com/s/u7qZp7ifUZoty8d8McH5QA(腾讯)

猜你喜欢

转载自blog.csdn.net/jun5753/article/details/81039624