APK瘦身:资源混淆、图片压缩、动态库按需加载、AndResGuard

APK太大,用户下载意愿低,这是每个Android开发者都会遇到的痛点。我记得几年前做一个社交App,功能还没加多少,APK已经奔着50MB去了。用户反馈说“你这App比游戏还大”,搞得我挺尴尬的。今天咱们就聊聊APK瘦身的几个实用招数。

为什么APK会越来越大?

说白了,APK膨胀的原因就那么几个:

  • 资源文件太多——图片、布局、字符串,尤其是多语言和多密度适配
  • 第三方库臃肿——一个库可能带了一堆你用不上的功能
  • Native库全平台打包——arm64、armeabi、x86全塞进去
  • 代码混淆不到位——类名、方法名还是可读的,压缩率低

我个人的习惯是,每次发版前都跑一遍APK Analyzer,看看哪个模块最占空间。嗯,下面这张图可以帮你快速理解APK瘦身的整体思路:

APK瘦身核心策略 APK瘦身 资源混淆 图片压缩 动态库按需加载 AndResGuard 代码混淆(ProGuard) 综合运用可减少APK体积30%~50%

资源混淆:让资源名变短

资源混淆,说白了就是把 R.drawable.ic_user_avatar_default 这种长名字,变成 R.drawable.a 这种短名字。你想想看,一个资源名可能占几十个字节,成百上千个资源加起来,体积就上去了。

我在项目中遇到过最夸张的情况——一个老项目,资源文件命名特别规范,规范到每个名字都超过30个字符。混淆之后,光资源名字符串就省了将近200KB。

核心思路:资源混淆只改资源名称,不改资源内容。它不影响代码逻辑,但能有效减小resources.arsc文件的大小。

图片压缩:最直接的瘦身方式

图片通常是APK里最占空间的。我建议你按这个优先级来处理:

  1. 能删就删——用不上的图片直接移除
  2. 能用Vector就别用PNG——矢量图体积小,适配好
  3. WebP格式优先——同等质量下,WebP比PNG小30%左右
  4. 压缩工具走一波——TinyPNG、ImageOptim都行

我的小技巧:在build.gradle里开启shrinkResources true,配合minifyEnabled true,Gradle会自动移除未引用的资源。但要注意,动态引用的资源可能会被误删,需要加tools:keep声明。

动态库按需加载:别把全平台库都塞进去

很多第三方SDK会提供全平台的Native库——arm64-v8a、armeabi-v7a、x86、x86_64。如果你一股脑全打包,APK体积直接翻倍。

我个人习惯的做法是:

  • 只保留arm64-v8a和armeabi-v7a——覆盖99%的Android设备
  • x86系列用兼容模式——或者干脆不打包,模拟器用户自己处理
  • 使用APK Split——按ABI分拆APK,用户下载时只下载对应架构的版本

配置方式很简单,在build.gradle里加:

android {
    splits {
        abi {
            enable true
            reset()
            include 'arm64-v8a', 'armeabi-v7a'
            universalApk false
        }
    }
}

注意:如果你用了某些需要Native库的SDK(比如人脸识别、音视频处理),一定要确认它们是否支持你保留的架构。我曾经因为漏了arm64-v8a的库,导致用户在高端机型上闪退,排查了半天才发现问题。

AndResGuard:资源保护的进阶方案

AndResGuard是微信团队开源的工具,它做的事情比普通资源混淆更彻底。它会:

  • 把资源路径变短(比如 res/drawable-hdpi 变成 r/d
  • 把资源文件名混淆成无意义短字符串
  • 对resources.arsc进行压缩优化

配置起来也不复杂:

apply plugin: 'AndResGuard'

andResGuard {
    mappingFile = null
    use7zip = true
    keepRoot = false
    // 白名单,某些资源不能混淆
    whiteList = [
        "R.drawable.ic_launcher",
        "R.string.app_name"
    ]
    compressFilePattern = [
        "*.png",
        "*.jpg",
        "*.jpeg",
        "*.gif",
        "*.webp"
    ]
}

嗯,这里要注意一点——AndResGuard和ProGuard是两回事。ProGuard混淆代码,AndResGuard混淆资源。两者配合使用,效果最好。

实战效果对比

我拿一个实际项目做过测试,原始APK大小是32MB。经过以下操作后:

优化手段 优化前 优化后 节省空间
图片转WebP + 压缩 15MB 9.2MB 5.8MB
移除冗余资源 9MB 6.5MB 2.5MB
动态库按需加载 5MB 2.8MB 2.2MB
AndResGuard混淆 32MB 28.5MB 3.5MB
总计 32MB 20.5MB 11.5MB

你看,综合运用下来,APK从32MB降到了20.5MB,省了将近36%。用户下载速度更快,留存率自然就上去了。

避坑指南:我曾经在某个版本里开启了AndResGuard的7zip压缩,结果发现华为某些机型安装时解析失败。后来查了半天,是因为7zip压缩后的APK在旧版Android上兼容性有问题。解决方案是——保留一个未压缩的版本作为备选,或者把7zip压缩关掉。

APK瘦身不是一锤子买卖,而是一个持续优化的过程。每次加新功能、新图片、新库的时候,都问自己一句:“这个真的需要吗?” 养成习惯后,你的APK自然会保持苗条。

公众号:蓝海资料掘金营,微信deep3321