助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
[TOC] 参见官方文档:[https://developer.android.com/topic/performance/reduce-apk-size?hl=zh-cn](https://developer.android.com/topic/performance/reduce-apk-size?hl=zh-cn) ## 了解APK结构 ![](https://img.kancloud.cn/97/65/9765ec02f7c6bef887f2c7cd1f583dac_951x609.png) ## 缩减APK大小 使用App Bundle上传应用不适用于国内环境,暂不介绍。App Bundle 针对不同用户的设备配置,提供经过优化的 APK,只需下载运行应用时所需的代码和资源,无需再编译、签署和管理多个 APK 以支持不同的设备。可以使用Android Size Analyzer插件或者命令行对项目进行分析,以确定哪些文件可以进行动态分发。 针对于国内的生态环境,我们主要从以下几个方面进行APK大小的优化: ### 缩减资源数量和大小 #### 1、移除不使用的资源文件 项目迭代过程中UI不断优化,部分资源文件不再使用,但仍存在于项目并被打包到APK中。可以使用`lint`工具来检测未被引用的资源文件。 >`lint`工具不会扫描`assets/`文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它也不会移除资源,只会提醒您它们的存在。 同时,可以在应用的`build.gradle`文件中启用[`shrinkResources`](https://developer.android.com/studio/build/shrink-code?hl=zh-cn#shrink-resources),Gradle 会自动为我们移除资源。 ```plain android { // Other settings buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } ``` #### 2、减少封装库中的资源使用量 #### 3、仅支持特定屏幕密度 目前市场上手机屏幕分辩率以1080P为主流,推荐应用包含一个`xxhdpi`图片变体即可,低密度的`ldpi`、`mdpi`、`hdpi`等可以考虑移除,Android 会自动缩放最初为其他屏幕密度设计的现有资源。 #### 4、使用可绘制对象 对于可以使用Drawable对象动态绘制的图片,如背景图等,推荐使用Drawable对象替代,其占用的空间会比静态图片资源小。 #### 5、重复使用资源 对于一些可以重复使用的图片资源,推荐替换色调调整、阴影设置、旋转等,重复使用。以下示例展示了通过绕图片中心位置旋转 180 度,将“拇指向上”变为“拇指向下”:: ```xml <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_thumb_up" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="180" /> ``` #### 6、压缩PNG文件 `aapt`工具可以在编译过程中通过无损压缩来优化放置在`res/drawable/`中的图片资源。例如,`aapt`工具可以通过调色板将不需要超过 256 种颜色的真彩色 PNG 转换为 8 位 PNG。这样做会生成质量相同但内存占用量更小的图片。 使用注意: * `aapt`工具不会缩减`asset/`文件夹中包含的 PNG 文件。 * 图片文件需要使用 256 种或更少的颜色才可供`aapt`工具进行优化。 * `aapt`工具可能会扩充已压缩的 PNG 文件。为防止出现这种情况,您可以在 Gradle 中使用`cruncherEnabled`标记为 PNG 文件停用此过程: ```plain aaptOptions { cruncherEnabled = false } ``` #### 7、压缩PNG和JPEG文件 可以使用[pngcrush](http://pmt.sourceforge.net/pngcrush/)、[pngquant](https://pngquant.org/)或[zopflipng](https://github.com/google/zopfli)等工具缩减 PNG 文件的大小,同时不损失画质。所有这些工具都可以缩减 PNG 文件的大小,同时保持肉眼感知的画质不变。 `pngcrush`工具尤为有效:该工具会迭代 PNG 过滤器和 zlib (Deflate) 参数,使用过滤器和参数的每个组合来压缩图片。然后,它会选择可产生最小压缩输出的配置。 要压缩 JPEG 文件,可以使用[packJPG](http://www.elektronik.htw-aalen.de/packjpg/)和[guetzli](https://github.com/google/guetzli)等工具。 #### 8、使用 WebP 文件格式 使用[WebP](https://developers.google.com/speed/webp/?hl=zh-cn)文件格式的图片(而不是使用 PNG 或 JPEG 文件)。Android Studio提供了转换单张图片或整个目录为WebP格式的方法,具体可参考[https://developer.android.com/studio/write/convert-webp?hl=zh-cn](https://developer.android.com/studio/write/convert-webp?hl=zh-cn) #### 9、使用矢量图形 可以使用矢量图形创建与分辨率无关的图标和其他可伸缩媒体。 #### 10、将矢量图形用于动画图片 请勿使用`[AnimationDrawable](https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable?hl=zh-cn)`创建逐帧动画,这样做需要为动画的每个帧添加单独的位图文件,而这会大大增加 APK 的大小。 应改为使用[`AnimatedVectorDrawableCompat`](https://developer.android.com/reference/androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat?hl=zh-cn)创建[动画矢量可绘制资源](https://developer.android.com/training/material/animations?hl=zh-cn#AnimVector)。 ### 减少原生和Java代码 #### 1、移除不必要的生成代码 确保了解自动生成的任何代码所占用的空间。例如,许多协议缓冲区工具会生成过多的方法和类,这可能会使应用的大小增加一倍或两倍。 #### 2、避免使用枚举 单个枚举会使应用的`classes.dex`文件增加大约 1.0 到 1.4KB 的大小。这些增加的大小会快速累积,产生复杂的系统或共享库。如果可能,请考虑使用`@IntDef`注释和[代码缩减](https://developer.android.com/studio/build/shrink-code?hl=zh-cn)移除枚举并将它们转换为整数。此类型转换可保留枚举的各种安全优势。 #### 3、缩减原生二进制文件的大小 如果您的应用使用原生代码和 Android NDK,还可以通过优化代码来缩减发布版应用的大小。移除调试符号和不提取原生库是两项很实用的技术。 ### 总结 综上可见,缩减APK大小主要从缩减资源文件和缩减原生及Java代码两方面入手,着重关注以下几点: * 移除未使用的资源文件 * 使用可绘制对象 * 压缩图片文件,优先使用WebP格式文件 * 避免使用枚举 * 仅打包有需要平台的so文件