随着项目迭代,新功能的增加。回导致apk越大。那么在下载安装过程中。用户耗费的流量越多。
安装等待的时间也会越长。这就意味着下载转化率会越低。那么如何apk瘦身呢?
在讨论怎么减小Apk体积之前,理解一个应用的APK结构是非常有帮助的。一个apk文件就是由一个zip压缩包组成,这个zip包含了所有组成你应用的文件。这些文件包含了java的字节码文件,资源文件和一个包含了编译后资源的文件。
一个apk包含了如下的目录:
一个APK还包含了如下的文件,但是其中只有AndroidManifest.xml是必须的。
可以看到占用空间的主要是代码、图片、资源和lib和assert文件,主要方向精简代码、压缩图片、去除无用的库、减少asserts里面文件。
在proguard中,是否保留符号表对APP的大小是有显著的影响的,可酌情不保留,但是建议尽量保留用于调试
参数:
-include {filename} 从给定的文件中读取配置参数
-basedirectory {directoryname} 指定基础目录为以后相对的档案名称
-injars {class_path} 指定要处理的应用程序jar,war,ear和目录
-outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。
保留选项 :
keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
压缩 :
-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}
优化 :
-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
混淆 :
dontobfuscate 不混淆输入的类文件
-printmapping {filename}
-applymapping {filename} 重用映射增加混淆
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量
在gradle使用shrinkResources去除无用资源,效果非常好。
android {
buildTypes {
release {
shrinkResources true
}
}
}
大部分应用其实并不需要支持几十种语言的国际化支持。还好强大的gradle支持语言的配置,比如国内应用只支持中文:
android {
defaultConfig {
resConfigs "zh"
}
}
进入Android Studio的菜单中选择Analyze->Inspecting Code即可。找到Unused resource这一栏打开,即是未被使用的资源列表,用户可以参照来手动删除资源
对于绝大多数app来说,只需要取一套设计图就足够了,考虑主流的趋势,建议采取720p的资源放到xhdpi,在视觉上差别不大。
很多大公司的产品都是如此。单却能显著的减少资源占用大小。同时也嫩减轻设计师的出图的工作量
对于ldpi,系统会自动的将hdpi的图片缩放到达到目的,所以你就不需要把ldpi的图片拷贝到你的res文件夹下了
也可在gradle中配置、
defaultConfig {
// ...
resConfigs "en", "de", "fr", "it"
resConfigs "hdpi", "xhdpi", "xxhdpi"
}
你能使用工具来减少PNG图片的体积但是不损失他的质量。如果对于非透明的大图,jpg将会比png的大小有显著的优势,
TinyPNG工具只支持上传PNG图片到官网上压缩,然后下载保存,在保持alpha通道的情况下对PNG的压缩可以达到1/3之内,而且用肉眼基本上分辨不出压缩的损失.
Tinypng的官方网站:http://tinypng.com/
如果对于非透明的大图,jpg将会比png的大小有显著的优势,虽然不是绝对的,但是通常会减小到一半都不止。
在启动页,活动页等之类的大图展示区采用jpg将是非常明智的选择。
webp支持透明度,压缩比比jpg更高。但是显示效果却不输于jpg .官方评测quality参数等75均衡最佳
基本上armable的so也是兼容armable-V7。x86机型是需要X86的。建议实际工作的配置只考虑armable、armable-x86下的so
矢量图、使用shape背景替换图片、避免重复库、清理第三方库和冗余代码、插件化等方式