好的,我们来详细分析 Android APK 的组成以及如何减小 APK 体积。这是 Android 开发中非常重要的优化环节。
一、 APK 组成结构
当你解压一个 APK 文件时,会看到类似这样的结构:
app.apk
├── AndroidManifest.xml # 二进制格式的清单文件
├── classes.dex # 编译后的代码
├── resources.arsc # 编译后的资源索引表
├── res/ # 资源文件(图片、布局等)
├── assets/ # 原始资源文件
├── lib/ # 原生库(.so 文件)
│ ├── arm64-v8a/
│ ├── armeabi-v7a/
│ └── x86/
└── META-INF/ # 签名信息
二、各组成部分详解
1. DEX 文件 (classes.dex, classes2.dex…)
- 内容:编译后的 Java/Kotlin 代码
- 占比:通常 20-40%
- 特点:方法数超过 65536 时会生成多个 dex 文件
2. 资源文件 (res/)
- 内容:图片、布局、字符串、颜色等
- 占比:通常 30-60%
- 分类:
- 可绘制资源(PNG, JPEG, WebP, Vector)
- 布局文件(XML)
- 值文件(strings, colors, dimens)
3. 原生库 (lib/)
- 内容:C/C++ 编译的 .so 文件
- 占比:依赖第三方库数量
- 架构:
armeabi-v7a
:32位 ARMarm64-v8a
:64位 ARMx86
,x86_64
:Intel 架构
4. 资源索引表 (resources.arsc)
- 内容:所有资源的索引和配置
- 作用:快速根据资源 ID 查找对应资源
5. Assets
- 内容:原始文件(字体、配置文件、游戏资源等)
- 特点:不会编译,原样打包
6. AndroidManifest.xml
- 内容:应用配置信息
- 特点:编译为二进制格式
三、 APK 体积优化策略
1. 代码优化
启用代码压缩和混淆
// app/build.gradle
android {
buildTypes {
release {
minifyEnabled true // 启用代码压缩
shrinkResources true // 移除无用资源
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
配置 ProGuard/R8 规则
# proguard-rules.pro
# 保留必要的类和方法
-keep class com.example.model.** { *; }
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 移除日志代码
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
}
使用 D8 编译器
android {
// D8 是默认编译器,生成更小的 DEX 文件
buildFeatures {
dexingPreview true
}
}
2. 资源优化
移除无用资源
android {
buildTypes {
release {
shrinkResources true
}
}
}
手动检查并移除:
# 使用 Lint 查找无用资源
./gradlew lint
图片资源优化
使用 WebP 格式
# 转换 PNG 到 WebP(通常减少 30% 体积)
# 在 Android Studio 中右键图片 → Convert to WebP
使用矢量图(Vector Drawable)
<!-- 代替多套 PNG,一个文件适配所有分辨率 -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#FF000000"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
配置图片资源限制
android {
defaultConfig {
// 只保留特定分辨率的图片
resConfigs "en", "zh", "xxhdpi"
}
}
优化资源引用
<!-- 避免 -->
<resources>
<string name="app_name">My App</string>
<string name="welcome_message">Welcome to My App</string>
</resources>
<!-- 推荐:使用字符串格式化 -->
<string name="welcome_message">Welcome to %s</string>
3. 原生库优化
配置支持的 ABI
android {
defaultConfig {
ndk {
// 只打包主流架构
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
}
// 或者分架构打包
splits {
abi {
enable true
reset()
include 'arm64-v8a', 'armeabi-v7a'
universalApk false
}
}
}
评估是否需要原生库
- 检查是否真的需要 JNI 代码
- 考虑使用纯 Java/Kotlin 替代方案
4. 使用 Android App Bundle
AAB vs APK:
- AAB:上传到 Play Store,Google 为不同设备生成优化后的 APK
- APK:通用包,包含所有资源
android {
bundle {
language {
// 启用语言拆分
enableSplit = true
}
density {
// 启用密度拆分
enableSplit = true
}
abi {
// 启用 ABI 拆分
enableSplit = true
}
}
}
5. 功能模块化
使用动态功能模块
// build.gradle (动态功能模块)
apply plugin: 'com.android.dynamic-feature'
android {
// 配置按需下载
dynamicFeatures = [":feature_payment"]
}
延迟加载非核心功能
// 检查功能模块是否已安装
val manager = SplitInstallManagerFactory.create(context)
val request = SplitInstallRequest.newBuilder()
.addModule("feature_payment")
.build()
manager.startInstall(request)
6. 其他优化策略
优化资源配置
android {
aaptOptions {
// 不压缩已有压缩格式的文件
noCompress 'pdf', 'mp4', 'ogg'
// 启用 cruncher 处理
cruncherEnabled = true
}
}
使用资源别名
<!-- 避免重复资源 -->
<resources>
<item name="primary_color" type="color">@color/blue_500</item>
<item name="secondary_color" type="color">@color/blue_300</item>
</resources>
四、分析和监控工具
1. APK 分析器 (Android Studio)
位置:Build → Analyze APK
功能:可视化分析 APK 组成
2. Gradle 分析任务
# 分析依赖树
./gradlew app:dependencies
# 分析构建时间
./gradlew build --profile
3. 自定义体积监控
// 在 build.gradle 中添加体积检查
android {
applicationVariants.all { variant ->
variant.outputs.all { output ->
def size = output.outputFile.length() / (1024 * 1024)
println "APK size: ${size} MB"
if (size > 100) {
throw new GradleException("APK size exceeds 100MB limit!")
}
}
}
}
五、实践总结
优化类别 | 具体措施 | 预期效果 |
---|---|---|
代码 | ProGuard/R8 混淆压缩 | 减少 20-40% |
资源 | WebP/矢量图 + 资源压缩 | 减少 30-60% |
原生库 | ABI 过滤 + 架构拆分 | 减少 50-80% |
分发 | Android App Bundle | 减少 15-50% |
架构 | 动态功能模块 | 核心包减少 40-70% |
1.推荐优化流程
- 分析现状:使用 APK 分析器确定主要体积来源
- 代码优化:启用混淆,移除无用代码
- 资源优化:转换图片格式,移除无用资源
- 原生库优化:配置 ABI 过滤
- 架构优化:模块化设计,使用动态交付
- 持续监控:设置体积阈值,定期检查
通过系统性的优化,通常可以将 APK 体积减少 50% 以上,显著提升用户下载和安装体验。