Gradle 从 Groovy 到 KTS 迁移
Posted 川峰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gradle 从 Groovy 到 KTS 迁移相关的知识,希望对你有一定的参考价值。
本文主要记录Groovy版本和kotlin版本的Gradle 相关设置。以便备忘或以后迁移参考。
settings.gradle
settings.gradle
:
pluginManagement
// 所有Gradle插件的下载远程仓库地址
repositories
gradlePluginPortal()
//google()
//mavenCentral()
// 阿里云镜像
maven url 'https://maven.aliyun.com/repository/central'
maven url 'https://maven.aliyun.com/repository/public'
maven url 'https://maven.aliyun.com/repository/jcenter'
maven url 'https://maven.aliyun.com/repository/google'
maven url 'https://maven.aliyun.com/repository/releases'
maven url 'https://maven.aliyun.com/repository/snapshots'
maven url 'https://maven.aliyun.com/repository/gradle-plugin'
dependencyResolutionManagement
// 所有模块依赖库的下载远程仓库地址
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories
//google()
//mavenCentral()
// 阿里云镜像
maven url 'https://maven.aliyun.com/repository/central'
maven url 'https://maven.aliyun.com/repository/public'
maven url 'https://maven.aliyun.com/repository/jcenter'
maven url 'https://maven.aliyun.com/repository/google'
maven url 'https://maven.aliyun.com/repository/releases'
maven url 'https://maven.aliyun.com/repository/snapshots'
maven url 'https://maven.aliyun.com/repository/gradle-plugin'
rootProject.name = "My Application"
include ‘:app’
settings.gradle.kts
:
pluginManagement
// 所有Gradle插件的下载远程仓库地址
repositories
gradlePluginPortal()
//google()
//mavenCentral()
// 阿里云镜像
maven(url = "https://maven.aliyun.com/repository/central")
maven(url = "https://maven.aliyun.com/repository/public")
maven(url = "https://maven.aliyun.com/repository/jcenter")
maven(url = "https://maven.aliyun.com/repository/google")
maven(url = "https://maven.aliyun.com/repository/releases")
maven(url = "https://maven.aliyun.com/repository/snapshots")
maven(url = "https://maven.aliyun.com/repository/gradle-plugin")
dependencyResolutionManagement
// 所有模块依赖库的下载远程仓库地址
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories
//google()
//mavenCentral()
// 阿里云镜像
maven(url = "https://maven.aliyun.com/repository/central")
maven(url = "https://maven.aliyun.com/repository/public")
maven(url = "https://maven.aliyun.com/repository/jcenter")
maven(url = "https://maven.aliyun.com/repository/google")
maven(url = "https://maven.aliyun.com/repository/releases")
maven(url = "https://maven.aliyun.com/repository/snapshots")
maven(url = "https://maven.aliyun.com/repository/gradle-plugin")
rootProject.name = "My Application"
include ‘:app’
推荐使用阿里云的Maven镜像仓库地址,下载速度很快。
根目录 build.gradle
build.gradle
:
ext
sdkVersion = 33
appcompatVersion = "1.6.0"
...
plugins
// apply false只能用于顶层build.gradle文件,切勿写在子模块中
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
build.gradle.kts
:
ext
extra["sdkVersion"] = 33
extra["appcompatVersion"] = "1.6.0"
...
plugins
// apply false只能用于顶层build.gradle文件,切勿写在子模块中
id("com.android.application") version "7.3.1" apply false
id("com.android.library") version "7.3.1" apply false
id("org.jetbrains.kotlin.android") version "1.7.21" apply false
子模块 build.gradle
build.gradle
:
plugins
id 'com.android.application'
android
// 每个 Android 模块都有一个命名空间,此命名空间用作其生成的 R 和 BuildConfig 类的 Java 或 Kotlin 软件包名称。
namespace 'com.example.myapp'
compileSdk 33
defaultConfig
applicationId 'com.example.myapp'
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"
manifestPlaceholders = [hostName:"www.example.com"]
javaCompileOptions
annotationProcessorOptions
argument 'key1', 'value1'
argument 'key2', 'value2'
kapt
includeCompileClasspath false
signingConfigs
release
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
buildTypes
release
minifyEnabled true // Enables code shrinking for the release build type.
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
debug
applicationIdSuffix ".debug" // 在 applicationId 后面追加一段
debuggable true
staging
initWith debug // 允许您从其他构建类型复制配置,然后只配置您想更改的设置。
manifestPlaceholders = [hostName:"internal.example.com"]
applicationIdSuffix ".debugStaging"
flavorDimensions "tier"
productFlavors
free
dimension "tier"
applicationId 'com.example.myapp.free'
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
paid
dimension "tier"
applicationId 'com.example.myapp.paid'
applicationIdSuffix ".full"
versionNameSuffix "-full"
// 过滤变体
variantFilter variant ->
def names = variant.flavors*.name
// To check for a certain build type, use variant.buildType.name == "<buildType>"
if (names.contains("minApi21") && names.contains("demo"))
// Gradle ignores any variants that satisfy the conditions above.
setIgnore(true)
sourceSets
main
java.srcDirs = ['other/java']
res.srcDirs = ['other/res1', 'other/res2']
manifest.srcFile 'other/AndroidManifest.xml'
...
androidTest
setRoot 'src/tests'
...
configurations
// 将产品变种和 build 类型组合在一起的变体添加依赖项,就必须在 configurations 代码块中初始化配置名称。
freeDebugRuntimeOnly
dependencies
implementation project(":lib")
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation files('libs/foo.jar', 'libs/bar.jar')
freeImplementation 'com.google.firebase:firebase-ads:9.8.0'
freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
// 排除传递依赖项
implementation('some-library')
exclude group: 'com.example.imgtools', module: 'native'
// 从测试配置中排除传递依赖项
android.testVariants.all variant ->
variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
compileOnly 'com.google.dagger:dagger:version-number'
// 注意:Android Plugin for Gradle 3.0.0 及更高版本不再支持 android-apt 插件
annotationProcessor 'com.google.dagger:dagger-compiler:version-number'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.0.2'
build.gradle.kts
:
plugins
id("com.android.application")
android
// 每个 Android 模块都有一个命名空间,此命名空间用作其生成的 R 和 BuildConfig 类的 Java 或 Kotlin 软件包名称。
namespace = "com.example.myapp"
compileSdk = 33
defaultConfig
applicationId = "com.example.myapp"
minSdk = 21
targetSdk = 33
versionCode = 1
versionName = "1.0"
manifestPlaceholders["hostName"] = "www.example.com"
javaCompileOptions
annotationProcessorOptions
arguments += mapOf("key1" to "value1",
"key2" to "value2")
kapt
includeCompileClasspath = false
signingConfigs
create("release")
storeFile = file("myreleasekey.keystore")
storePassword = "password"
keyAlias = "MyReleaseKey"
keyPassword = "password"
buildTypes
getByName("release")
isMinifyEnabled = true // Enables code shrinking for the release build type.
proguardFiles(
getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("release")
getByName("debug")
applicationIdSuffix = ".debug" // 在 applicationId 后面追加一段
isDebuggable = true
create("staging")
initWith(getByName("debug")) // 允许您从其他构建类型复制配置,然后只配置您想更改的设置。
manifestPlaceholders["hostName"] = "internal.example.com"
applicationIdSuffix = ".debugStaging"
flavorDimensions += "tier"
productFlavors
create("free")
dimension = "tier"
applicationId = "com.example.myapp.free"
applicationIdSuffix = ".demo"
versionNameSuffix = "-demo"
create("paid")
dimension = "tier"
applicationId = "com.example.myapp.paid"
applicationIdSuffix = ".full"
versionNameSuffix = "-full"
sourceSets.getByName("main")
java.setSrcDirs(listOf("other/java"))
res.setSrcDirs(listOf("other/res1", "other/res2"))
manifest.srcFile("other/AndroidManifest.xml")
...
sourceSets.getByName("androidTest")
setRoot("src/tests")
...
// 过滤变体
androidComponents
beforeVariants variantBuilder ->
// To check for a certain build type, use variantBuilder.buildType == "<buildType>"
if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo")))
// Gradle ignores any variants that satisfy the conditions above.
variantBuilder.enable = false
// 将产品变种和 build 类型组合在一起的变体添加依赖项,就必须在 configurations 代码块中初始化配置名称。
val freeDebugRuntimeOnly by configurations.creating
dependencies
implementation(project(":lib"))
implementation("androidx.appcompat:appcompat:1.6.0")
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
implementation(files("libs/foo.jar", "libs/bar.jar"))
freeImplementation("com.google.firebase:firebase-ads:9.8.0")
freeDebugRuntimeOnly(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
// 排除传递依赖项
implementation("some-library")
exclude(group = "com.example.imgtools", module = "native")
// 从测试配置中排除传递依赖项
android.testVariants.all
compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
compileOnly("com.google.dagger:dagger:version-number")
// 注意:Android Plugin for Gradle 3.0.0 及更高版本不再支持 android-apt 插件
annotationProcessor("com.google.dagger:dagger-compiler:version-number")
testImplementation("junit:junit:4.12")
androidTestImplementation("androidx.test.espresso:espresso-core:3.0.2")
子模块build.gradle 引用全局属性
build.gradle
:
android
compileSdk rootProject.ext.sdkVersion
...
...
dependencies
implementation "androidx.appcompat:appcompat:$rootProject.ext.appcompatVersion"
...
build.gradle.kts
:
android
compileSdk = rootProject.extra["sdkVersion"]
val sdkVersion: Int by rootProject.extra // 可以使用kotlin委托语法
...
compileSdk = sdkVersion
...
dependencies
implementation("androidx.appcompat:appcompat:$rootProject.ext.appcompatVersion")
...
为每个变体创建动态版本号
groovy
:
android
...
defaultConfig
...
versionCode 4
splits
...
// Map for the version code that gives each ABI a value.
ext.abiCodes = ['armeabi-v7a':1, mips:2, x86:3]
// For per-density APKs, create a similar map like this:
// ext.densityCodes = ['hdpi': 1, 'xhdpi': 2, 'xxhdpi': 3, 'xxxhdpi': 4]
import com.android.build.OutputFile
// For each APK output variant, override versionCode with a combination of
// ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
android.applicationVariants.all variant ->
// Assigns a different version code for each output APK
// other than the universal APK.
variant.outputs.each output ->
// Stores the value of ext.abiCodes that is associated with the ABI for this variant.
def baseAbiVersionCode =
// Determines the ABI for this variant and returns the mapped value.
project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
// Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
// the following code does not override the version code for universal APKs.
// However, because we want universal APKs to have the lowest version code,
// this outcome is desirable.
if (baseAbiVersionCode != null)
// Assigns the new version code to versionCodeOverride, which changes the version code
// for only the output APK, not for the variant itself. Skipping this step simply
// causes Gradle to use the value of variant.versionCode for the APK.
output.versionCodeOverride =
baseAbiVersionCode * 1000 + variant.versionCode
kotlin
:
android
...
defaultConfig
...
versionCode = 4
splits
...
// Map for the version code that gives each ABI a value.
val abiCodes = mapOf("armeabi-v7a" to 1, "mips" to 2, "x86" to 3)
// For per-density APKs, create a similar map like this:
// val densityCodes = mapOf("hdpi" to 1, "xhdpi" to 2, "xxhdpi" to 3, "xxxhdpi" to 4)
import com.android.build.api.variant.FilterConfiguration.FilterType.*
// For each APK output variant, override versionCode with a combination of
// abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
androidComponents
onVariants variant ->
// Assigns a different version code for each output APK
// other than the universal APK.
variant.outputs.forEach output ->
val name = output.filters.find it.filterType == ABI ?.identifier
// Stores the value of abiCodes that is associated with the ABI for this variant.
val baseAbiCode = abiCodes[name]
// Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
// the following code does not override the version code for universal APKs.
// However, because we want universal APKs to have the lowest version code,
// this outcome is desirable.
if (baseAbiCode != null)
// Assigns the new version code to output.versionCode, which changes the version code
// for only the output APK, not for the variant itself.
output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0))
查看传递依赖项
在gradle面板中执行androidDependencies
任务即可:
AAR 中的原生依赖项
Gradle 模块中的 AAR 依赖项可公开原生库供您的应用使用。
以上是关于Gradle 从 Groovy 到 KTS 迁移的主要内容,如果未能解决你的问题,请参考以下文章
如何在 gradle kts 中排除(忽略)android 构建变体