第2章:Android SDK开发环境搭建与版本管理(Java/Kotlin、Gradle、MinSDK等)
这一章,我们聊聊环境搭建和版本管理。说实话,这步看着基础,但SDK兼容性测试的根基就在这里。我见过太多人因为Android SDK版本没配好,最后测试环境跟生产环境不一致,白白浪费了宝贵的测试时间。
你想想看,一个数据分类SDK要跑在成千上万的设备上。如果开发环境都不稳,那后面所有测试都像是在沙子上盖房子。
2.1 开发环境链路概览
我先把整条环境链路理一遍。一条干净的工具链,能帮你省下70%的排查时间。
2.2 JDK与Gradle版本管理
JDK版本,我建议统一用JDK 17。 为什么?因为从Android Gradle Plugin 8.x开始,官方正式要求JDK 17支持。我之前项目里,就因为JDK版本不同导致JNI库加载失败,排查了整整一个下午。
.java-version 文件(用 jEnv 工具),确保团队所有成员本地JDK一致。这种小事,往往是最容易出问题的。
Gradle版本,尽量保持跟AGP(Android Gradle Plugin)大版本匹配。
| AGP 版本 | 最低 Gradle 版本 | 我建议的 Gradle 版本 | 备注 |
|---|---|---|---|
| 7.x | 7.5 | 7.6.x | 旧项目过渡用 |
| 8.0 - 8.1 | 8.0 | 8.2 | 稳定版本 |
| 8.2+ | 8.2 | 8.4 或 8.5 | 推荐新项目使用 |
有次我接手一个数据采集SDK项目,里面还在用AGP 4.2和Gradle 6.7。编译一次要5分钟,而且各种警告。升级到AGP 8.x后,编译时间缩短到1分钟以内,而且很多废弃API的检查自动生效。
2.3 Kotlin / Java 语言版本配置
对于SDK开发,我倾向于用Kotlin + Java 11的混合模式。数据分类SDK里,核心逻辑用Kotlin协程处理,底层IO操作有时还是Java更稳。
注意 compileOptions 里的 sourceCompatibility 和 targetCompatibility。
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
}
kotlinOptions.jvmTarget,结果编译出来的字节码版本不匹配,在Android 12设备上运行时抛出 UnsupportedOperationException。这个问题非常隐蔽,因为编译不会报错,只有运行到特定API才会暴露。
2.4 MinSdk / TargetSdk / CompileSdk 三件套
这三者的关系,说白了就是“你用什么编译”、“你最低支持到哪”、“你适配的目标版本是什么”。
- compileSdk: 用最新的(比如34)。让你能调用的API最多,编译检查也最严。
- minSdk: 根据你的SDK用户群体定。数据分类SDK如果面向大型App,通常minSdk=21(Android 5.0)或更高。我个人习惯定在24左右。
- targetSdk: 这个必须小心。它决定了系统会对你施加哪些行为变更(Behavior Changes)。你测试时必须用targetSdk对应的设备版本来验证。
android {
compileSdk = 34
defaultConfig {
minSdk = 24
targetSdk = 33 // 建议保守一点,让系统行为变更可控
}
}
我曾经遇到过:targetSdk设为34后,Android 14的“非线性通知”机制导致我们的数据分类服务被系统频繁切断。幸好我们在兼容性测试中提前发现了。
2.5 版本号与依赖管理
版本号管理看似简单,但坑很多。数据分类SDK的版本号通常由 versionCode(数字,严格递增)和 versionName(字符串,语义化)组成。
| 字段 | 用途 | 建议 | 我在项目中遇到过的坑 |
|---|---|---|---|
| versionCode | 内部递增,用于市场判断 | 用时间戳或构建流水线ID | 手动设置 -> 漏跟版本 -> 上线被回滚 |
| versionName | 对外展示 | Semantic Versioning (major.minor.patch) | 建议同步到Git Tag |
另外,依赖版本的锁定也很关键。Gradle的 constraints 和 platform 可以帮助你统一依赖版本,避免依赖地狱。
dependencies {
constraints {
implementation("com.google.code.gson:gson:2.10.1") {
because("要求2.10.1版本以修复CVE-2022-xxxxx")
}
}
}
2.6 构建变体(Build Variants)与测试
对于SDK兼容测试,我至少要配置两个变体:debug 和 release。
为什么?因为release版本会经过混淆(R8/ProGuard)和资源缩减。
建议在 build.gradle.kts 里设置如下规则:
android {
buildTypes {
debug {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
2.7 工程化与版本锁定
我建议所有项目成员都使用 gradle-wrapper.properties 和 gradle/libs.versions.toml(Gradle版本目录)来统一版本。
举个例子,你的 gradle/libs.versions.toml 文件可以这样写:
[versions]
agp = "8.2.0"
kotlin = "1.9.22"
gson = "2.10.1"
[libraries]
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
然后在构建脚本里引用:
plugins {
id("com.android.library") version "8.2.0" apply false
}
这样做的最大好处: 版本变更只需要改一个文件,CI/CD流水线也能自动获取最新版本。降低人为错误。
compileSdk 或 targetSdk 后,都会用 adb shell dumpsys package 检查一下当前设备的运行时权限和后台限制是否被触发。这个步骤能帮你发现一些很难复现的兼容性问题。
2.8 小结
环境搭建和版本管理,是整个SDK兼容性测试的“地基”。地基稳了,后面所有测试才有意义。我觉得你这会儿可以先去检查一下自己项目的 build.gradle.kts,看看 minSdk 和 targetSdk 是否都在预期范围内。