Android特有配置:minSdk/targetSdk/compileSdk、ndkVersion、aaptOptions、dexOptions、资源优化
说实话,Android的Gradle配置里,有一块内容是纯纯的「Android味儿」。不像依赖管理或者构建变体那样通用,这些配置只属于Android生态。今天我们就来聊聊这些特有配置,我把它们分成三块:SDK版本三兄弟、NDK与AAPT、以及Dex与资源优化。
1. SDK版本三兄弟:minSdk、targetSdk、compileSdk
这三个字段,几乎是每个Android项目的标配。但很多人只是照着模板填,并不清楚它们各自管什么。我刚开始做Android时也犯过糊涂——把compileSdk和targetSdk当成一回事,结果踩了不少坑。
核心区别一句话总结:
- compileSdk:告诉Gradle,你可以用哪个版本的API来编译代码。
- minSdk:你的App最低能跑在哪个Android版本上。
- targetSdk:你声明自己已经针对哪个API版本做过充分测试。
举个例子,你compileSdk设成34,就能用Android 14的新API。但minSdk设成21,意味着App在Android 5.0上也能安装。targetSdk设成33,表示你在Android 13上测试过,系统不会对你做向后兼容的行为变更。
我个人习惯是:compileSdk永远用最新,这样能第一时间用上新API和lint检查。targetSdk我会比compileSdk低一个版本,等充分测试后再追平。minSdk则根据产品需求定,一般我会设成当前市场占有率前95%的最低版本。
我曾经踩过的坑:有一次我把targetSdk从30升到31,结果App在Android 12上启动就崩溃。查了半天,原来是Android 12对PendingIntent的FLAG_IMMUTABLE要求更严格了。所以升级targetSdk时,一定要仔细看行为变更文档。
2. ndkVersion:NDK版本锁定
如果你的项目用到了C/C++代码(比如通过JNI调用),那就需要配置NDK版本。以前很多人不写ndkVersion,让Gradle自动选。但这样有个问题——不同开发机上的NDK版本可能不一样,导致编译结果不一致。
我建议在android块里显式声明:
android {
ndkVersion "25.1.8937393"
}
这样团队里所有人都用同一个NDK版本,避免「我这儿能编译,你那儿不行」的尴尬。你可以在local.properties里指定本地NDK路径,但版本号还是写在build.gradle里更靠谱。
3. aaptOptions:资源打包的精细控制
aaptOptions控制的是Android资源打包工具(AAPT2)的行为。说实话,大部分项目不需要动它。但如果你遇到资源冲突或者想压缩资源,这里就有用武之地了。
常用的几个配置:
android {
aaptOptions {
// 忽略某些资源文件
ignoreAssetsPattern "!*.bak:!*.swp"
// 关闭PNG压缩(加快构建速度)
cruncherEnabled false
// 额外传递给AAPT的参数
additionalParameters "--no-version-vectors"
}
}
我记得有个项目,资源文件里混入了很多.bak备份文件,导致APK体积莫名其妙变大。加上ignoreAssetsPattern后,问题立刻解决。
小技巧:如果你用Vector Drawable,可以加上--no-version-vectors参数。这样AAPT不会为低版本生成PNG回退图,能省不少APK体积。
4. dexOptions:DEX文件的调优
DEX是Android的可执行文件格式。当你的代码量很大时,DEX配置就变得重要了。尤其是方法数超过65535时,你需要开启MultiDex。
常见的dexOptions配置:
android {
dexOptions {
// 最大堆内存,防止OOM
javaMaxHeapSize "4g"
// 是否预编译DEX(加快构建)
preDexLibraries true
// 线程数
maxProcessCount 4
}
}
这里我要特别说一下javaMaxHeapSize。如果你在构建时遇到OutOfMemoryError,八成是DEX编译时堆内存不够。我一般设成4g,如果项目特别大,可以设到6g甚至8g。
注意:preDexLibraries在Android Gradle Plugin 3.0以后默认就是true,而且效果有限。如果你用Instant Run或者新版的构建缓存,这个配置基本不用动。
5. 资源优化:shrinkResources与resConfigs
资源优化是APK瘦身的利器。两个最常用的配置:shrinkResources和resConfigs。
shrinkResources:配合ProGuard/R8使用,自动移除未引用的资源。
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
resConfigs:只保留你需要的语言资源,去掉那些用不上的翻译。
android {
defaultConfig {
resConfigs "zh", "en"
}
}
我做过一个项目,只支持中文和英文,但依赖的第三方库带了30多种语言资源。加上resConfigs "zh", "en"后,APK直接瘦了2MB。你想想看,这效果多明显。
避坑指南:shrinkResources一定要配合minifyEnabled使用,否则不会生效。而且它只移除未引用的资源,不会帮你压缩图片。图片压缩还得靠WebP或者TinyPNG。
知识体系总览
下面这张图把本章的核心知识点串了起来,方便你对照理解:
这张图把五个核心配置模块串在了一起。你可以看到,SDK版本是基础,NDK和AAPT是进阶控制,DEX和资源优化则是构建后期的调优手段。每个模块之间没有强依赖关系,但组合起来能让你的构建配置更健壮、更高效。
好了,这一章的内容就到这里。配置这东西,光看文档是不够的,建议你打开自己的项目,对照着检查一遍。尤其是shrinkResources和resConfigs,改完立竿见影。