Android Apk瘦身优化:可以瘦身的模块有哪些?

198 阅读5分钟

一、瘦身的目的

APK 瘦身是通过技术手段减少安装包体积的优化过程,目的是:

  1. ​提升用户体验​​:加快下载速度,降低安装失败率(尤其在网络差或存储不足的设备上)。
  2. ​降低分发成本​​:减少应用商店流量消耗和服务器存储压力。

二、APK 中可以瘦身的模块

1. ​​代码优化​
  • ​ProGuard/R8​​:混淆、删除未使用的代码(如废弃功能、测试代码)。
  • ​D8 编译器​​:优化字节码,减少生成的 DEX 文件体积。
2. ​​资源优化​
  • ​删除无用资源​​:shrinkResources true 自动移除未引用的资源。
  • ​资源压缩​​:
    • 图片转 WebP/AVIF(比 PNG 小 30% 以上)。
    • 矢量图替代位图(适用于简单图标)。
3. ​​so 库优化​
  • ​仅保留必要架构​​:比如只支持 arm64-v8a(覆盖 95% 以上设备),放弃 armeabi

三、APK结构

AndroidManifest.xml应用的全局配置(包名、权限、组件声明、SDK 版本要求等),二进制格式。删除冗余权限或 uses-feature 声明,避免过度声明硬件支持。
classes.dex包含 Java/Kotlin 代码编译后的 DEX 字节码文件(可能多个,如 classes2.dex)。通过 ProGuard 移除无用代码,D8/R8 优化字节码,减少 DEX 数量和体积。
resources.arsc编译后的资源索引表(资源 ID、类型、路径映射)。压缩资源路径名(混淆),删除未使用的语言或分辨率配置。
res/存放编译后的资源文件(图片、布局、字符串等),按类型和分辨率分类。删除未引用资源,压缩图片格式(WebP/AVIF),矢量图替代位图。
assets/原始资源文件(如配置文件、字体),需通过 AssetManager 访问。按需动态加载非必要资源,压缩文本类资源(如 JSON)。
lib/Native 库(.so 文件),按 CPU 架构分类(armeabi-v7a, arm64-v8a 等)。仅保留主流架构(如 arm64-v8a),或动态下载特定架构库。
META-INF/包含应用签名信息(MANIFEST.MF, CERT.SF, CERT.RSA)。无直接优化空间,但需确保签名有效性。

图片.png

可以点击——Build——Analyze APK——看看apk那个部分比较大,可以优化一下。

四、瘦身优化

4.1 资源混淆、移除未使用资源

1. minifyEnabled(代码压缩与混淆)​

​定义​​: 用于启用 ​​代码压缩、混淆和优化​​,核心目标是减少代码体积并保护代码逻辑。

​功能​​:

  1. ​删除未使用的代码​​:移除未被引用的类、方法、字段(如废弃功能、调试代码)。
  2. ​代码混淆​​:将类名、方法名、变量名替换为简短的无意义名称(如 ab)。
  3. ​代码优化​​:简化逻辑(如内联短方法、删除冗余代码)。

优化效果​​:

  • ​DEX 体积减少​​:通常可减少 10%-30% 的代码体积。
  • ​安全性提升​​:混淆后的代码难以逆向分析。
2. shrinkResources(资源压缩)​

​定义​​: 用于删除 ​​未被代码引用的资源文件​​(如图片、布局、字符串),减少资源体积。

​依赖条件​​: 必须与 minifyEnabled true 同时启用,因为它依赖代码分析结果判断资源是否被使用。

优化效果​​:

  • ​资源体积减少​​:移除未使用的图片、布局等,通常减少 5%-20% 的资源体积。

  • ​保留资源白名单​​:可通过 res/raw/keep.xml 指定强制保留的资源:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/force_keep_layout, @drawable/keep_image"
    tools:discard="@layout/unsed2"/>

如果使用了discard属性,那么哪怕你使用到了资源,也会删除。

android {
    buildTypes {
        release {
            minifyEnabled true     // 必须同时启用
            shrinkResources true   // 删除未使用的资源
        }
    }
}
3. AndResGuard(资源压缩)​

AndResGuard 是腾讯开源的一款 Android 资源混淆工具,通过缩短资源文件(图片、布局、字符串等)的路径和名称,优化资源索引表(resources.arsc)的结构,从而减少 APK 体积并增强安全性。

  • 资源路径混淆​​:将冗长的资源路径(如 res/drawable-xxhdpi/icon_home.png)替换为短路径(如 r/d/a.png)。

  • ​资源名称混淆​​:将资源名称替换为无意义的短字符串。

  • ​索引表优化​​:压缩 resources.arsc 的体积(减少字符串存储空间)。

如何使用 AndResGuard?​
​步骤 1:集成插件​

在项目根目录的 build.gradle 中添加依赖:

buildscript {
    dependencies {
        classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.21'
    }
}
​步骤 2:配置混淆规则​

app/build.gradle 中配置 AndResGuard:

apply plugin: 'AndResGuard'

andResGuard {
    enable = true  // 启用资源混淆
    // 白名单(保留不被混淆的资源)
    whiteList = [
        "R.drawable.icon_launcher",  // 启动图标(避免动态加载失败)
        "R.string.app_name",         // 应用名称(某些系统功能依赖)
        "R.xml.firebase_config"      // Firebase 配置文件
    ]
    // 压缩图片(可选)
    compressFilePattern = ["*.png", "*.jpg", "*.webp"]
    // 输出目录
    outputDir = "apk_resguard"
}
​步骤 3:构建混淆后的 APK​

运行以下命令生成混淆包:

./gradlew resguardRelease

输出路径:app/apk_resguard/Release/app-release-resguard.apk

​步骤 4:验证结果​
  1. ​体积对比​​:比较混淆前后 APK 的 resources.arsc 和资源目录体积。
  2. ​反编译检查​​:使用 Android Studio 的 ​​Analyze APK​​ 或 apktool 解压 APK,确认资源路径已缩短。

shrinkResources trueAndResGuard的区别是:仅删除未使用的资源,不混淆路径。但是你会发现,为什么有些xml文件,明明开启了缩减,还是存在呢,因为他不是剔除,而是优化变小,没有内容了,几十B

4.2 移除未使用的备用资源

一般开发我们都会引入各种依赖,这些依赖可能包含各种备用资源,如中文、英文、日韩文等等。如果我们不需要这些语言可以让他们不打包进入Apk

图片.png

可以如下配置,减少这些语言

图片.png

图片.png

4.3 so库优化

SO(Shared Object)是 Android 平台上的动态链接库,用于存放 C/C++ 编写的原生代码(Native Code),位于项目的 jniLibs/ 目录或第三方库的 lib/ 目录下。每个 CPU 架构对应一个 SO 文件目录(如 arm64-v8aarmeabi-v7a)。

arm64-v8a64 位 ARM 架构(主流设备)
armeabi-v7a32 位 ARM 架构(旧设备)
x8632 位 Intel 架构(模拟器或旧设备)
x86_6464 位 Intel 架构(模拟器)
移除不必要的架构​

app/build.gradle 中配置 ndk.abiFilters,仅保留目标架构:

android {
    defaultConfig {
        ndk {
            abiFilters "arm64-v8a" // 只保留 64 位 ARM 架构
        }
    }
}

​优化效果​​:若一个 SO 文件原为 5 MB,支持 4 种架构时总大小为 ​​20 MB​​,保留 1 种后仅 ​​5 MB​​。