在Android Gradle Plugin 升级到9.0后,谷歌官方会推荐我们使用build-logic。通过统一构造plugin,在多个module中,可以对他们的build.gradle进行统一管理,减少重复代码,十分方便。
创建build-logic文件夹
-
在根目录下新建文件夹,"build-logic"。
-
在build-logic文件夹下,新建gradle文件"settings.gradle.kts"。
pluginManagement {
repositories {
maven { url = uri("https://maven.aliyun.com/repository/public") }
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/central") }
maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
google {
content {
includeGroupByRegex("com\.android.*")
includeGroupByRegex("com\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven { url = uri("https://maven.aliyun.com/repository/public") }
maven { url = uri("https://maven.aliyun.com/repository/google") }
maven { url = uri("https://maven.aliyun.com/repository/central") }
google()
mavenCentral()
}
// 注意这个,添加libs的映射关系
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "build-logic"
// 等会添加
// include(":convention")
- 在根目录中的"settings.gradle.kts"中,将我们的这个"build-logic"加入gradle中。
pluginManagement {
includeBuild("build-logic")
repositories {
/// ...
}
}
- 编译一下项目,应该可以看到,build-logic被Android Studio识别成了模块,说明是正常了
新建convention模块
-
在build-logic文件夹下,新建文件夹"convention"。
-
在"convention"文件夹中,新建build.gradle.kts文件
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
`kotlin-dsl`
}
group = "com.zq.myapplication.buildlogic.convention"
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_17
}
}
dependencies {
// TODO 用来添加模块中用到的依赖
}
gradlePlugin {
plugins {
// TODO 用来注册
}
}
- 在根目录gradle文件夹下的libs.versions.toml文件中,添加用到的plugin依赖,注意是library下。
[libraries]
#build-logic
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle-api", version.ref = "androidGradlePlugin" }
android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" }
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
compose-gradlePlugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" }
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
[plugins]
...
- 在"convention"下的build.gradle.kts中,添加依赖
dependencies {
// 注意这边只需要compileOnly就行
compileOnly(libs.android.gradlePlugin)
compileOnly(libs.android.tools.common)
compileOnly(libs.compose.gradlePlugin)
compileOnly(libs.kotlin.gradlePlugin)
compileOnly(libs.ksp.gradlePlugin)
}
-
在"convention"下新建文件夹src/main/kotlin,给后续添加文件使用
-
在"build-logic"的settings.gradle.kts下,将convention模块添加
pluginManagement {
repositories {
// ...
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
// ...
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "build-logic"
// 添加convention模块
include(":convention")
- 再次编译一下项目,convention模块通过。
添加application的plugin类
- 在convention模块中新建一个类AndroidApplicationConventionPlugin
class AndroidApplicationConventionPlugin: Plugin<Project> {
override fun apply(target: Project) {
with(target) {
// 引入,标记为application
apply(plugin = "com.android.application")
// application 的 android { }
extensions.configure<ApplicationExtension> {
defaultConfig.targetSdk = 36
}
}
}
}
- 前往libs.versions.toml文件中,在[plugin]下添加一个自定义的id
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
/// ...
# build-logic
myapplication-android-application = { id = "myapplication.android.application" }
- 我们需要将这个id,跟我们实际的类AndroidApplicationConventionPlugin,进行一个绑定的方法。在convention模块下的build.gradle.kts中,添加映射关系。
gradlePlugin {
plugins {
register("androidApplication") {
id = libs.plugins.myapplication.android.application.get().pluginId
implementationClass = "AndroidApplicationConventionPlugin"
}
}
}
- 最后编译一下项目
使用自定义plugin
在app的build.gradle.kts中进行使用, 这样就可以了
plugins {
alias(libs.plugins.myapplication.android.application)
}
Tips
- 关于对application和library的区分,以及使用
// application 的 android { }
extensions.configure<ApplicationExtension> {
}
// 当我依赖了application时,会执行下面方法
pluginManager.withPlugin("com.android.application") {
}
// library 的 android { }
extensions.configure<LibraryExtension> {
}
// 当我依赖了library时,会执行下面方法
pluginManager.withPlugin("com.android.library") {
}
-
Android Gradle Plugin 9.0中,默认gradle.properties中会开启buildInKotlin, 从而我们不需要主动依赖"org.jetbrains.kotlin.android"。
-
在自定义plugin中,应用plugin时,不需要加版本号,gradle会自动查找
apply(plugin = "com.android.application")
但是要注意,需要你在根目录的build.gradle.kts中添加,可能才能生效
[plugins]
room = { id = "androidx.room", version.ref = "room" }
plugins {
alias(libs.plugins.room) apply false
}
class AndroidRoomConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
apply(plugin = "androidx.room")
apply(plugin = "com.google.devtools.ksp")
// 让room生成kotlin
extensions.configure<KspExtension> {
arg("room.generateKotlin", "true")
}
// room存储生成的文件
extensions.configure<RoomExtension> {
schemaDirectory("$projectDir/schemas")
}
dependencies {
"implementation"(libs.findLibrary("room-runtime").get())
"implementation"(libs.findLibrary("room-ktx").get())
"implementation"(libs.findLibrary("room-paging").get())
"ksp"(libs.findLibrary("room-compiler").get())
}
}
}
}