
好的,我们来详细分析 Android APK 的组成以及如何减小 APK 体积。这是 Android 开发中非常重要的优化环节。
当你解压一个 APK 文件时,会看到类似这样的结构:
app.apk
├── AndroidManifest.xml # 二进制格式的清单文件
├── classes.dex # 编译后的代码
├── resources.arsc # 编译后的资源索引表
├── res/ # 资源文件(图片、布局等)
├── assets/ # 原始资源文件
├── lib/ # 原生库(.so 文件)
│ ├── arm64-v8a/
│ ├── armeabi-v7a/
│ └── x86/
└── META-INF/ # 签名信息armeabi-v7a:32位 ARMarm64-v8a:64位 ARMx86, x86_64:Intel 架构// app/build.gradle
android {
buildTypes {
release {
minifyEnabled true // 启用代码压缩
shrinkResources true // 移除无用资源
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}# 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(...);
}android {
// D8 是默认编译器,生成更小的 DEX 文件
buildFeatures {
dexingPreview true
}
}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>android {
defaultConfig {
ndk {
// 只打包主流架构
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
}
// 或者分架构打包
splits {
abi {
enable true
reset()
include 'arm64-v8a', 'armeabi-v7a'
universalApk false
}
}
}AAB vs APK:
android {
bundle {
language {
// 启用语言拆分
enableSplit = true
}
density {
// 启用密度拆分
enableSplit = true
}
abi {
// 启用 ABI 拆分
enableSplit = true
}
}
}// 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)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>位置:Build → Analyze APK 功能:可视化分析 APK 组成
# 分析依赖树
./gradlew app:dependencies
# 分析构建时间
./gradlew build --profile// 在 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% |
通过系统性的优化,通常可以将 APK 体积减少 50% 以上,显著提升用户下载和安装体验。