属性与优先级
源:Gradle 官方文档 - Build Environment
当属性配置来自多个源时,理解优先级顺序是排查"配置不生效"问题的关键。
属性来源
Gradle 属性可以来自以下多个位置,优先级从高到低:
命令行参数 → 系统属性 → 环境变量 → gradle.properties → 默认值
优先级顺序
命令行参数 最高优先级
项目属性:
bash
./gradlew build -Pversion=1.0.1 -PenableFeature=true在构建脚本中访问:
kotlin
val version: String by project
val enableFeature: String by project系统属性:
bash
./gradlew build -Dorg.gradle.daemon=false系统环境变量
格式:ORG_GRADLE_PROJECT_<property_name>
bash
export ORG_GRADLE_PROJECT_version=1.0.1
export ORG_GRADLE_PROJECT_enableFeature=true使用:
kotlin
val version: String by project // 自动从环境变量读取用户主目录 gradle.properties
位置:~/.gradle/gradle.properties
properties
# ~/.gradle/gradle.properties
org.gradle.jvmargs=-Xmx4096m
repo_username=myusername
repo_password=mypassword用途:
- 全局 JVM 配置
- 个人凭证
- 开发环境配置
项目根目录 gradle.properties
位置:<project-root>/gradle.properties
properties
# gradle.properties
org.gradle.parallel=true
android.useAndroidX=true
app_version_name=1.0.0用途:
- 项目团队共享配置
- 项目特定属性
- Android 配置
子项目 gradle.properties
位置:<project-root>/<sub project>/gradle.properties
properties
# app/gradle.properties
custom_property=value优先级示例
假设三个位置都定义了 myProperty:
properties
# ~/.gradle/gradle.properties
myProperty=global
# <project-root>/gradle.properties
myProperty=project
# 命令行
./gradlew build -PmyProperty=command最终值:command(命令行优先级最高)
系统属性 vs 项目属性
项目属性
定义方式:
bash
./gradlew build -Pkey=valueproperties
# gradle.properties
key=valuebash
export ORG_GRADLE_PROJECT_key=value访问方式:
kotlin
val key: String by project
val key = project.findProperty("key") as? String
val hasKey = project.hasProperty("key")用途:
- 构建逻辑控制
- 版本号
- 功能开关
系统属性
定义方式:
bash
./gradlew build -Dkey=valueproperties
# gradle.properties
systemProp.key=value访问方式:
kotlin
val key = System.getProperty("key")用途:
- JVM 配置
- 代理设置
- Gradle 运行参数
安全读取属性
使用 findProperty
❌ 不安全:
kotlin
val version: String by project // 属性不存在时抛异常✅ 安全:
kotlin
val version: String? = project.findProperty("version") as? String
val versionOrDefault = project.findProperty("version") as? String ?: "1.0.0"检查属性存在
kotlin
if (project.hasProperty("enableFeature")) {
val feature: String by project
// 使用属性
}类型转换
kotlin
val port = project.findProperty("server.port") as? String
val portInt = port?.toIntOrNull() ?: 8080
val enabled = project.findProperty("feature.enabled") as? String
val isEnabled = enabled?.toBoolean() ?: falseCI/CD 环境配置
GitHub Actions
yaml
# .github/workflows/build.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
env:
ORG_GRADLE_PROJECT_version: ${{ github.run_number }}
ORG_GRADLE_PROJECT_api_key: ${{ secrets.API_KEY }}
run: ./gradlew buildJenkins
groovy
// Jenkinsfile
environment {
ORG_GRADLE_PROJECT_version = "${env.BUILD_NUMBER}"
ORG_GRADLE_PROJECT_is_ci = "true"
}
steps {
sh './gradlew build'
}GitLab CI
yaml
# .gitlab-ci.yml
variables:
ORG_GRADLE_PROJECT_version: $CI_PIPELINE_IID
ORG_GRADLE_PROJECT_is_ci: "true"
build:
script:
- ./gradlew build调试属性值
打印属性
kotlin
// build.gradle.kts
gradle.projectsEvaluated {
println("version = ${project.findProperty("version")}")
println("enableFeature = ${project.findProperty("enableFeature")}")
}列出所有属性
kotlin
project.properties.forEach { (key, value) ->
println("$key = $value")
}命令行查看
bash
# 查看所有属性
./gradlew properties
# 过滤特定属性
./gradlew properties | grep version实践案例
多环境配置
properties
# gradle.properties
env=dev
api_base_url=https://dev-api.example.combash
# 生产环境构建
./gradlew build -Penv=prod -Papi_base_url=https://api.example.com使用:
kotlin
val env: String by project
val apiBaseUrl: String by project
android {
defaultConfig {
buildConfigField("String", "API_BASE_URL", "\"${apiBaseUrl}\"")
buildConfigField("String", "ENV", "\"${env}\"")
}
}功能开关
properties
# gradle.properties
feature_new_ui=falsekotlin
val featureNewUi = project.findProperty("feature_new_ui") as? String
dependencies {
if (featureNewUi?.toBoolean() == true) {
implementation("com.example:new-ui:1.0.0")
} else {
implementation("com.example:old-ui:2.0.0")
}
}版本控制
bash
# CI 环境
export ORG_GRADLE_PROJECT_versionCode=$BUILD_NUMBER
export ORG_GRADLE_PROJECT_versionName="1.0.$BUILD_NUMBER"kotlin
val versionCode: String? by project
val versionName: String? by project
android {
defaultConfig {
versionCode = versionCode?.toInt() ?: 1
versionName = versionName ?: "1.0.0"
}
}最佳实践
使用环境变量传递敏感信息:
- CI/CD 中使用 Secret
- 本地使用全局 gradle.properties
- 永不提交密码到版本控制
提供默认值:
- 使用
findProperty和?: - 避免构建失败
- 提升开发体验
文档化属性:
- 在 README 中说明必需属性
- 提供示例配置
- 说明默认值
优先级应用:
- 开发环境:使用项目 gradle.properties
- CI 环境:使用环境变量
- 临时覆盖:使用命令行参数
安全读取:
- 总是使用
findProperty - 检查
null值 - 提供合理默认值