一个 App 的包之所以大, 主要包括一下文件
代码
lib
so 本地库
资源文件(图片, 音频, 字体等)
瘦身就主要瘦这些.
一, 打包的時候刪除不用的代码
- buildTypes {
- debug {
- ...
- shrinkResources true // 是否去除无效的资源文件(如果你的 Debug 也需要瘦身)
- }
- release {
- ...
- shrinkResources true // 是否去除无效的资源文件
- }
- }
二, 减少不必要的打包
- defaultConfig {
- ...
- // 打包的语言类型(语种的翻译)
- resConfigs "en", "de", "fr", "it"
- // 打包的文件夹
- resConfigs "nodpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"
- }
或者
- Android {
- ...
- splits {
- density {
- enable true
- exclude "ldpi", "tvdpi", "xxxhdpi"
- compatibleScreens 'small', 'normal', 'large', 'xlarge'
- //reset()
- //include 'x86', 'armeabi-v7a', 'mips'
- //universalApk true
- }
- }
三, lib
尽量不用太复杂的 lib, 轻量级 lib 是首选. 如果你的应用没用到兼容库, 可以考虑去掉 support 包.
四, 资源文件
我们可以通过 Lint 工具找到没有使用的资源(在 Android Studio 的 "Analyze" 菜单中选择 "Inspect Code...")
五, 把现有图片转换为 webP
我们可以通过 智图 或者 isparta 将其它格式的图片转换成 webP 格式, isparta 可实现批量转换.
五, 图片相关
在 Android 5.0 及以上的版本可以通过 tintcolor 实现只提供一张按钮的图片, 在程序中实现按钮反选效果, 前提是图片的内容一样, 只是正反选按钮的颜色不一样.
Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )
在 Android 5.0 及以上的版本, 可以使用 VectorDrawable 和 SVG 图片来替换原有图片
六, 混淆
1 构建多个版本
在 gradle 中的 buildTypes 中增加不同的构建类型, 使用 applicationSuffix 和 versionNameSuffix 可以生成多个版本在同一设备上运行
创建
src/[buildType]/res/
设置不同的 ic_launcher 以区别不同版本
2 混淆参数
- {
- debug { minifyEnabled false }
- release {
- signingConfig signingConfigs.release
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
- minifyEnabled true
是否要启用通过 ProGuard 实现的代码压缩(true 启用)
请注意, 代码压缩会拖慢构建速度, 因此您应该尽可能避免在调试构建中使用.
注: Android Studio 会在使用 Instant Run 时停用 ProGuard.
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
getDefaultProguardFile('proguard-android.txt')方法可从 Android SDKtools/proguard / 文件夹获取默认 ProGuard 设置.
提示: 要想做进一步的代码压缩, 可尝试使用位于同一位置的 proguard-Android-optimize.txt 文件. 它包括相同的 ProGuard 规则, 但还包括其他在字节码一级 (方法内和方法间) 执行分析的优化, 以进一步减小 APK 大小和帮助提高其运行速度.
proguard-rules.pro 文件用于添加自定义 ProGuard 规则. 默认情况下, 该文件位于模块根目录(build.gradle 文件旁).
要添加更多各构建变体专用的 ProGuard 规则, 请在相应的 productFlavor 代码块中再添加一个 proguardFiles 属性. 例如, 以下 Gradle 文件会向 flavor2 产品风味添加 flavor2-rules.pro. 现在 flavor2 使用所有三个 ProGuard 规则, 因为还应用了来自 release 代码块的规则.
每次构建时 ProGuard 都会输出下列文件 dump.txt 说明 APK 中所有类文件的内部结构. mapping.txt: 提供原始与混淆过的类, 方法和字段名称之间的转换. seeds.txt: 列出未进行混淆的类和成员. usage.txt: 列出从 APK 移除的代码. 这些文件保存在 / build/outputs/mapping/release/.
要修正错误并强制 ProGuard 保留特定代码, 请在 ProGuard 配置文件中添加一行 - keep 代码. 例如:
-keeppublicclassMyClass
您还可以向您想保留的代码添加[@Keep]
(https://developer.android.com/reference/android/support/annotation/Keep.html)注解. 在类上添加 @Keep 可原样保留整个类. 在方法或字段上添加它可完整保留方法 / 字段 (及其名称) 以及类名称. 请注意, 只有在使用注解支持库时, 才能使用此注解.
在使用 - keep 选项时, 有许多事项需要考虑; 如需了解有关自定义配置文件的详细信息, 请阅读 ProGuard 手册. 问题排查一章概述了您可能会在混淆代码时遇到的其他常见问题.
请注意, 您每次使用 ProGuard 创建发布构建时都会覆盖 mapping.txt 文件, 因此您每次发布新版本时都必须小心地保存一个副本. 通过为每个发布构建保留一个 mapping.txt 文件副本, 您就可以在用户提交的已混淆堆叠追踪来自旧版本应用时对问题进行调试.
在每次添加库的时候, 需要及时进行 make a release build
DexGuard 时 Proguard 同一个团队开发的软件, 优化代码, 分离 dex 文件从而解决 65k 方法限制的文件
关于 proguard-Android.txt 文件:
-dontusemixedcaseclassnames: 表示混淆时不使用大小写混淆类名.
-dontskipnonpubliclibraryclasses: 不跳过 library 中的非 public 方法.
-verbose: 打印混淆的详细信息.
-dontoptimize: 不进行优化, 优化可能会造成一些潜在风险, 不能保证在所有版本的 Dalvik 上都正常运行.
-dontpreverify: 不进行预校验.
-keepattributes Annotation : 对注解参数进行保留.
- -keep public class com.google.vending.licensing.ILicensingService
- -keep public class com.Android.vending.licensing.ILicensingService:
表示不混淆上述声明的两个类.
proguard 中一共有三组六个 keep 关键字的含义
keep 保留类和类中的成员, 防止它们被混淆或移除.
keepnames 保留类和类中的成员, 防止它们被混淆, 但当成员没有被引用时会被移除.
keepclassmembers 只保留类中的成员, 防止它们被混淆或移除.
keepclassmembernames 只保留类中的成员, 防止它们被混淆, 但当成员没有被引用时会被移除.
keepclasseswithmembers 保留类和类中的成员, 防止它们被混淆或移除, 前提是指名的类中的成员必须存在, 如果不存在则还是会混淆.
keepclasseswithmembernames 保留类和类中的成员, 防止它们被混淆, 但当成员没有被引用时会被移除, 前提是指名的类中的成员必须存在, 如果不存在则还是会混淆.
keepclasseswithmember 和 keep 关键字的区别:
如果这个类没有 native 的方法, 那么这个类会被混淆
- -keepclasseswithmember class * {
- native <methods>;
- }
不管这个类有没有 native 的方法, 那么这个类不会被混淆
- -keep class * {
- native <methods>;
- }
另外, 你可以使用 APK Analyser 分解你的 APK
Android Studio 提供了一个有用的工具: APK Analyser.APK Analyser 将会拆解你的应用并让你知道 .apk 文件中的那个部分占据了大量空间. 让我们看一下 Anti-Theft 在没有经过优化之前的截图.
从 Apk Analyser 的输出来看, 应用的原大小是 3.1MB. 经过 Play 商店的压缩, 大致是 2.5MB.
从截图中可以看出主要有 3 个文件夹占据了应用的大多数空间.
classes.dex -- 这是 dex 文件, 包含了所有会运行在你的 DVM 或 ART 里的字节码文件.
res -- 这个文件夹包含了所有在 res 文件夹下的文件. 大部分情况下它包含所有图片, 图标和源文件, 菜单文件和布局.
resources.arsc -- 这个文件包含了所有 value 资源. 这个文件包含了你 value 目录下的所有数据. 包括 strings,dimensions,styles,intergers,ids 等等.
你有两个默认的混淆文件.
- proguard-Android-optimize.txt
- proguard-Android.txt
就像文件名写的那样,"proguard-android-optimize.txt" 是更积极的混淆选项. 我们将这个作为默认的混淆配置. 你可以在 /App 目录下的 proguard-rules.pro 里添加自定义的混淆配置.
- release {
- //Enable the proguard
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), "proguard-rules.pro"
- //Other parameters
- debuggable false
- jniDebuggable false
- renderscriptDebuggable false
- signingConfig playStoreConfig //Add your own signing config
- pseudoLocalesEnabled false
- zipAlignEnabled true
- }
通过设置 minifyEnabled 为 true, 混淆将会移除所有未使用的方法, 指令以减小 classes.dex 文件.
这是启用了 minify 之后的 APK.
七, AndroidStudio 使用 lint 清除无用的资源文件
在使用 AndroidStudio 进行 App 开发的时候, 我们经常会在项目中引用多种资源文件, 包括图片, 布局文件, 常量引用定义. 随着项目版本开发的迭代, 每一期的资源会有变动必定会留下一些无用的资源这个时候我们手动去一个一个寻找效率就会很低下. 这个时候我们就要学会 AndroidStudio 使用 lint 清除无用的资源文件.
打开 AndroidStudio 在项目中, 点击最上方的菜单栏 Analyze -> Run Inspection by Name 如下图:
点击 Run Inspection by Name 会弹出一个对话框. 在对话框里面输入 unused resource 如下图:
然后点击下拉列表中的 unused resource. 之后会弹出一个对话框如下图
最后
如果你看到了这里, 觉得文章写得不错就给个赞呗? 如果你觉得那里值得改进的, 请给我留言. 一定会认真查询, 修正不足. 谢谢.
希望读到这的您能转发分享和关注一下我, 以后还会更新技术干货, 谢谢您的支持!
转发 + 点赞 + 关注, 第一时间获取最新知识点
Android 架构师之路很漫长, 一起共勉吧!
------ 分割线 ------
简书点赞可以有好几种赞, 长按点赞按钮就会有选项, 大家点赞的时候, 麻烦点个超赞, 让我感受下这个功能......
来源: http://www.jianshu.com/p/ee4d096850f9