image
公司项目在不断的改版迭代中, 代码在不断的累加, 终于 apk 包不负重负了, 已经到了八十多 M 了. 可能要换种方式表达, 到目前为止没有正真的往外推过, 一直在内部执行 7 天讨论需求, 5 天代码实现的阶段. 你在写上个版本的内容, 好了, 下个版本的更新内容已经定稿了. 基于这种快速开发的现状, 我们 App 优化前已经有 87.1M 了, 包大了, 运营说这样转化不高, 只能好好搞一下咯. 优化过后包大小为 23.1M(优化了 73%, 不要说我标题党). 好了好了, 我要阐述我的 apk 超级无敌魔鬼瘦身之心得了.
目录如下图:
文章主要内容从理论出发, 再做实际操作. 分为下面几个方面:
1. 结构分析, 2. 具体实操
3. 总结
1. 结构分析
首先上传一张瘦身前通过 Analyze App 分析出来的图片 (打开方式: Android Studio 下 --> Build--> Analyze App):
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 格式.
通过分析图可以知道, 目前 App 主要是 so 文件占比比较大, 占了 31.7M, 占了整个应用是 38.2%. 其次是 assets 目录, 整个目录占了 32M, 第三就是资源文件 res 目录了. 所以接下来我们处理步骤就是按这个顺序来处理.(简单说下图中的 Raw File Size(磁盘解压后的大小) 和 DownLoad Size(从应用商店下载的大小), 如果想了解更多关于 Analyaer 分析的知识, 可以参考这篇文章使用 APK Analyzer 分析你的 APK), 分析了包结构组成之后, 我们可以开始瘦身操作了.
2. 具体实操
1. 对 lib 目录下的文件进行瘦身处理
1. 修改 lib 配置:
参考资料
so 文件的优化: 通常我们在使用 NDK 开发的时候, 我们经常会有如下这么一段代码:
- ndk {
- // 设置支持的 so 库架构
- abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64", "armeabi"
- }
![Android 性能优化之 APK 瘦身详解 (瘦身 73%)](https://upload-images.jianshu.io/upload_images/15217452-a164a611526fa4bc?imageMogr2/auto-orient/strip|imageView2/2/w/1240)
image.PNG
最后我的修改代码如下:
- ndk {
- // 设置支持的 so 库架构
- abiFilters "armeabi-v7a"
- }
接下来说明这么做的依据:
看上面图分析, armeabi-v7 主要不支持 ARMv5(1998 年诞生) 和 ARMv6(2001 年诞生). 目前这两款处理器的手机设备基本不在我公司的适配范围 (市场占比太少).
而许多基于 x86 的设备也可运行 armeabi-v7a 和 armeabi NDK 二进制文件. 对于这些设备, 主要 ABI 将是 x86, 辅助 ABI 是 armeabi-v7a.
最后总结一点: 如果适配版本高于 4.1 版本, 可以直接像我上面这样写, 当然, 如果 armeabi-v7a 不是设备主要 ABI, 那么会在性能上造成一定的影响.
好了, 我们再打一次包试试.
- buildTypes {
- release {
- // 不显示 Log
- buildConfigField "boolean", "LOG_DEBUG", "false"
- // 混淆
- minifyEnabled true
- // 移除无用的 resource 文件
- shrinkResources true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- signingConfig signingConfigs.release
- }
- }
来源: http://www.jianshu.com/p/d92876108b66