APK瘦身
随着业务迭代,apk体积逐渐变大。项目中积累的无用资源,未压缩的图片资源等,都为apk带来了不必要的体积增加。而APK 的大小会影响应用加载速度、使用的内存量以及消耗的电量。
APK 结构
APK 包含以下目录:
META-INF/ :包含 CERT.SF 和 CERT.RSA 签名文件,以及 MANIFEST.MF 清单文件。
assets/ :包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。
res/ :包含未编译到 resources.arsc 中的资源(图片、音视频等)。
lib/ :包含特定于处理器软件层的已编译代码。此目录包含每种平台类型的子目录,如 armeabi 、armeabi-v7a 、 arm64-v8a 、 x86 、 x86_64 和 mips 。现在常用要求的(arm64-v8a)其他可以不考虑
主要优化:assets,res,lib文件夹下的文件。
APK 还包含以下文件。
resources.arsc :包含了被编译的资源。该文件包含了res/values目录的所有配置的 xml 内容。打包工具将 xml 内容编译成二进制形式并压缩。这些内容包含了语言字符串和styles,还包含了那些内容虽然不直接存储在resources.arsc文件中,但是给定了该内容的路径,比如布局文件和图片。所以又叫 资源映射表。
classes.dex :包含以 Dalvik/ART 虚拟机可理解的 DEX 文件格式编译的类。
AndroidManifest.xml :包含了主要的Android配置文件。这个文件列出了应用名称、版本、访问权限、引用的库文件。该文件使用二进制 xml 格式存储。(译注:该文件还能看到应用的minSdkVersion, targetSdkVersion等信息)
Android Size Analyzer
Android Size Analyzer 工具可轻松地发现和实施多种缩减应用大小的策略
从菜单栏中依次选择 Analyze > Analyze App Size,对当前项目运行应用大小分
启用资源缩减
如果在应用的 build.gradle 文件中启用了资源缩减: shrinkResources,则 Gradle 在打包APK时可以自动忽略未使用资源。 资源缩减只有在与代码缩减:minifyEnabled 配合使用时才能发挥作用。在代码缩减器移除所有不使用的代码后,资源缩减器便可确定应用仍要使用的资源,从而在打包时优化这些资源 。
shrinkResources:资源压缩
minifyEnabled :代码压缩
移除未使用的备用资源
一般开发我们都会引入各种依赖,这些依赖可能包含各种备用资源,如中文、英文、日韩文等等。如果我们不需要这些语言(不做国际化需求)可以让他们不打包进入。Apk。
一键删除无用资源
Android Studio给我们提供了一键移除所有无用的资源。从菜单栏中依次选择 Refactor > Remove UnusedResources,但是这种方式不建议使用,因为如果某资源仅存在动态获取资源id 的方式,那么这个资源会被认为没有使用过,从而会直接被删除。
动态库打包配置
目前Android打包可以支持如下CPU架构:
armeabi-v7a: 第7代 ARM v7,使用硬件浮点运算,具有高级扩展功能(支持 armeabi 和 armeabi-v7a,目前大部分手机都是这个架构)。
arm64-v8a :第8代,64位,包含AArch32、AArch64两个执行状态对应32、64bit(支持 armeabi-v7a、armeabi 和 arm64-v8a)。
x86 intel 32位:少数的平板应用此架构(支持 armeabi(性能有所损耗) 和 x86)。
x86_64 :intel 64位,少数的平板应用此架构(支持 x86 和 x86_64)。
目前市面上手机设备绝大多数都是arm架构,因此armv7a几乎能兼容所有设备。大多数应用只会打包armv7a的so在Apk中。对于第三方服务,如百度地图、Bugly等会提供全平台的cpu架构。因此我们可以进行如下配置,指定只打包armv7a到apk,从而减少apk大小。
使用矢量图
矢量图可以创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以极大地减少 APK 占用的空间。 矢量图片在 Android 中以 VectorDrawable 对象的形式表示。借助 VectorDrawable 对象,100 字节的文件可以生成与屏幕大小相同的清晰图片。
不过,系统渲染每个 VectorDrawable 对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏幕上。因此,建议仅在显示小图片时使用这些矢量图
Tint着色器
虽然我们可以直接在 xml 文件中修改矢量图的颜色,但是并不建议直接修改,我们一般让矢量图为黑色,然后用 Tint 着色器去修改矢量图的颜色。
单个 多个其他
使用精简版本的依赖:如protobuf-lite版本;对于分模块的库按需引入:如netty分模块引入;
主动移除无用代码(开启R8/Progurad自动移除);
避免使用枚举,使用 @IntDef 代替;
不常用功能模块使用插件化加载;
开启资源混淆:https://github.com/shwenzhang/AndResGuard;
支付宝删除Dex debugItem https://juejin.im/post/6844903712201277448 ;
对于发布Google paly的应用选择使用:AAB https://developer.android.google.cn/guide/app-bundle
网友评论