gradle wrapper 旨在绕过本地 gradle 安装,强制使用项目声明的版本;它通过 gradlew 脚本读取 gradle-wrapper.properties 中的 distributionurl,自动下载并运行指定 gradle 版本,全程隔离本地环境。

Gradle Wrapper 本来就不该用本机安装的版本
Wrapper 的设计目标就是**绕过本地 Gradle 安装**,强制使用项目声明的版本。它不是“找不到才 fallback 到本地”,而是从头就隔离本地环境 —— gradlew 脚本里压根不查 PATH 或 GRADLE_HOME,只认 gradle/wrapper/gradle-wrapper.properties 里的 distributionUrl。
执行 gradlew 时到底发生了什么
当你运行 ./gradlew build,脚本会:
- 检查
gradle/wrapper/gradle-wrapper.jar是否存在(缺了就报Could not find or load main class org.gradle.wrapper.GradleWrapperMain) - 读取
gradle/wrapper/gradle-wrapper.properties中的distributionUrl(比如https://services.gradle.org/distributions/gradle-8.5-bin.zip) - 去
$HOME/.gradle/wrapper/dists/下找对应 hash 目录;没找到就下载解压,找到就直接启动其中的bin/gradle - 全程不调用系统 PATH 里的任何
gradle可执行文件
为什么 gradle 命令和 gradlew 命令结果不同
这是最常被误以为“出 bug”的地方,其实完全符合预期:
-
gradle build:走的是你本地 SDKMAN / 手动解压 / IDE 内置的 Gradle,版本由你机器决定 -
./gradlew build:只用项目配置的版本,哪怕你本地根本没装 Gradle 也能跑 - 二者可能因版本差异导致:
Plugin with id 'com.android.application' not found、Could not resolve com.android.tools.build:gradle、甚至静默跳过某些 task - Android Studio 默认也调用
gradlew,除非你在 Settings → Build → Build Tools → Gradle 中手动切换成 “Use Gradle from wrapper” 以外的选项
什么时候真需要本地 Gradle?怎么让它生效
极少数场景确实要绕过 Wrapper,比如:
- 调试 Gradle 本身(改源码、打 patch)
- 离线环境预装特定版本,并禁止网络下载(需提前把
gradle-8.6-bin.zip放进$HOME/.gradle/wrapper/dists/gradle-8.6-bin/xxx/对应 hash 目录) - CI 流水线为提速复用已缓存的本地 Gradle(但必须确保所有 job 使用相同版本,否则反而引入不一致)
想让 gradle 命令生效,得手动配好 GRADLE_HOME 和 PATH,且确认 gradle -v 输出与项目要求兼容 —— 但这和 Wrapper 无关,是纯本地运维行为。
真正容易被忽略的是:distributionUrl 里的版本必须和项目中 android gradle plugin(AGP)匹配。比如 AGP 8.4 要求 Gradle 8.6+,此时就算你本地装了 8.5,gradlew 也会坚持下载 8.6,不会妥协。











