摘要:记录一次诡异的 Android 编译报错经历。从
Could not find compile target android-36.0到AAR metadata版本冲突,最后发现罪魁祸首竟然是 Gradle DSL 中不起眼的minorApiLevel配置。
🐛 前言
在 Android 开发中,SDK 版本管理通常是件很省心的事。但今天,我遇到了一个极其刁钻的问题:明明 SDK 装了,IDE 却死活找不到;明明配置了 API 36,报错却让人摸不着头脑。
如果你也遇到了 Could not find compile target 或者 Dependency requires version 36 or later 的死循环,这篇博文或许能帮你省下一下午的排查时间。
🚨 事故现场
一切开始于一个普通的下午,打开项目,Android Studio 突然开始报红。
第一阶段:找不到目标 SDK
最直观的报错是 IDE 提示:
Error: Could not find compile target android-36.0 for modules :app
同时,Project Structure 界面提示我选择 SDK 位置。但我检查了 SDK Manager,Android 16.0 (API 36) 明明显示已安装。
![SDK Manager 截图示意]
此时的困惑:
- SDK 路径没问题。
- API 36 确实装了。
- 为什么 Gradle 还是找不到?
第二阶段:版本冲突的死循环
我不甘心,尝试降级到 API 35 看看能不能跑通。结果,控制台抛出了一堆 AAR metadata 错误:
text
编辑
Dependency 'androidx.core:core-ktx:1.18.0' requires libraries and applications that
depend on it to compile against version 36 or later of the Android APIs.
局面变得非常尴尬:
- 用 API 35:报错,因为
androidx.core:1.18.0等新库强制要求 API 36。 - 用 API 36:报错,IDE 提示找不到
android-36.0。
这就陷入了一个完美的死锁。
🔍 抽丝剥茧:排查过程
1. 检查 SDK Manager
我仔细盯着 SDK Manager 的列表看,发现 API 36 这一栏有点奇怪。它显示安装了,但版本号后面带了一些后缀,比如 36.0-ext18。
2. 检查 build.gradle
既然 SDK 没问题,那肯定是配置的问题。我打开了 build.gradle (KTS),检查 android 闭包。
kotlin
编辑
android {
// 这里的配置,就是罪魁祸首
compileSdk {
version = release(36) {
minorApiLevel = 1
}
}
// ...
}
看到这段代码时,我愣了一下。这是为了适配某些特定平台扩展而加的预览版配置。
关键点来了:
- 我的配置要求:
release(36)且minorApiLevel = 1。这实际上是在寻找 Extension Level 1。 - 我的 SDK Manager:安装的是 Extension Level 18/19 (
36.0-ext18)。
结论: Gradle 在硬盘里疯狂寻找 android-36-ext1,但我装的是 ext18。版本号不匹配,导致 IDE 认为“没装这个版本”,从而报出 Could not find compile target。
✅ 解决方案
既然找到了病灶,解决起来就非常简单粗暴了。
方案:移除 minorApiLevel 锁定
我们不需要锁定到具体的 minorApiLevel,只需要告诉 Gradle:“我要用 API 36,用我电脑上最新的就行”。
修改 build.gradle:
kotlin
编辑
android {
// 修改前:锁死在 ext1,导致找不到
// compileSdk {
// version = release(36) {
// minorApiLevel = 1
// }
// }
// 修改后:直接使用简写,Gradle 会自动匹配最新的 ext 版本
compileSdk = 36
defaultConfig {
targetSdk = 36 // 保持同步
// ...
}
}
修改后的效果:
Gradle 重新 Sync 时,会自动检测本地已安装的 API 36 包,发现 36.0-ext19 是最新的,于是自动适配。既满足了 androidx.core:1.18.0 对 API 36 的强制要求,又解决了 IDE 找不到 Target 的问题。
之所以加上 minorApiLevel = 1 就会报错,是因为你实际上是在告诉 Gradle:“请给我 Android 16 的第一个小版本更新(也就是 36.1)”。
让我们拆解一下这个配置的含义,你就明白为什么之前一直报错了:
你的配置到底写了什么?
你之前的代码:
kotlin
编辑
compileSdk {
version = release(36) {
minorApiLevel = 1
}
}
release(36):代表 Android 16 平台(API Level 36)。minorApiLevel = 1:代表 Extension Level 1。
这意味着,Gradle 会去寻找一个名为 android-36-ext1 的 SDK 包。
回头看你的 SDK Manager 截图
请再看一眼你刚才发的 SDK Manager 截图(图 2):
- 你安装的 API 36 显示为:
36.0-ext18和36.0-ext19。 - 你并没有安装
36.0-ext1!
这就是为什么 AS 一直报 Could not find compile target android-36.0 或者找不到对应的 target。Gradle 在你的硬盘里找 36.1,结果你装的是 36.18 和 36.19,或者根本没装对版本。
为什么删掉就好了?
当你删掉 { minorApiLevel = 1 } 后:
kotlin
编辑
compileSdk = 36
Gradle 的查找逻辑变成了:
“寻找 API Level 36 的 最新 可用版本”。
这时候,Gradle 扫描你的 SDK 文件夹,发现了你安装的 36.0-ext19(这是目前你电脑上最新的 36 版本),于是它自动使用了这个版本。
匹配成功!问题解决!
总结
minorApiLevel是用来指定特定的 平台扩展版本 的。除非你明确知道自己需要哪个特定的扩展包(比如为了测试某个特定的隐私沙盒功能),否则不要手动写这个配置。- 最佳实践:保持
compileSdk = 36(或者version = release(36))即可,让构建工具自动抓取最新的扩展版本。