
引言
维护一个拥有数十甚至上百个模块的大型 Android 项目很容易让人焦头烂额。不同团队负责不同功能模块,久而久之项目的构建逻辑就会逐渐"失控":各个模块依赖配置五花八门,插件应用方式参差不齐。
当遇到依赖库升级时,比如 Android发布新版本了、Kotlin版本要升级了、三方库出现 Breaking change 了等等,所有项目、所有模块都需要同步修改,而那些复制粘贴的重复构建逻辑早已散布在项目的各个角落。
但如果你的构建配置能够实现集中化、标准化和复用化呢?如果每个功能模块、核心库或主应用,只需应用一个插件就能自动遵循项目的统一规范呢?这正是 Gradle Convention Plugins (约定插件) 的用武之地。
这不就是 buildSrc 的用途吗?
虽然 buildSrc 曾经是集中管理 Gradle 逻辑的主流方案,但它有一个致命缺陷:buildSrc 目录下的任何修改,都会触发整个项目的全量重新构建------哪怕这个修改和绝大多数模块毫无关联。这对于大型 Android 项目来说,会严重拖慢构建速度。
而约定插件完美解决了这个问题:它的构建逻辑只需编译并缓存一次,就像普通插件一样运行,不会触发不必要的全量重构。同时,它更便于版本管理和测试,还能让你的build.gradle.kts 文件变得更简洁、更模块化。简而言之,约定插件既保留了集中式构建逻辑的所有优势,又避免了 buildSrc 带来的性能损耗。
快速上手
首先,创建一个名为 build-logic 的新目录,并在其中添加 settings.gradle.kts 文件:
kt
pluginManagement {
repositories {
gradlePluginPortal()
google()
}
}
dependencyResolutionManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "build-logic"
include(":convention")
在这个文件中,我们注册约定模块。接下来,创建该模块并在其 build.gradle.kts 文件中添加如下配置:
kt
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
`kotlin-dsl`
}
group = "com.example.template.buildlogic"
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_17
}
}
dependencies {
compileOnly(libs.android.gradleApiPlugin)
compileOnly(libs.kotlin.gradlePlugin)
compileOnly(libs.compose.gradlePlugin)
// Add any other needed external plugin like: KSP, Hilt, etc
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) // To allow getting version catalog references in convention plugins
}
gradlePlugin {
plugins { // Here we will register our custom plugins
// Android
register("androidApplication") {
id = libs.plugins.template.application.get().pluginId
implementationClass = "ApplicationConventionPlugin"
}
register("androidLibrary") {
id = libs.plugins.template.library.get().pluginId
implementationClass = "LibraryConventionPlugin"
}
// JVM
register("jvm") {
id = libs.plugins.template.jvm.get().pluginId
implementationClass = "JvmConventionPlugin"
}
// Compose
register("androidComposeApplication") {
id = libs.plugins.template.compose.application.get().pluginId
implementationClass = "ComposeApplicationConventionPlugin"
}
register("androidComposeLibrary") {
id = libs.plugins.template.compose.library.get().pluginId
implementationClass = "ComposeLibraryConventionPlugin"
}
// Koin
register("koinCore") {
id = libs.plugins.template.koin.core.get().pluginId
implementationClass = "KoinCoreConventionPlugin"
}
register("koinAndroid") {
id = libs.plugins.template.koin.android.get().pluginId
implementationClass = "KoinAndroidConventionPlugin"
}
// Flavors
register("FlavorApplication") {
id = libs.plugins.template.flavor.application.get().pluginId
implementationClass = "FlavorApplicationConventionPlugin"
}
register("FlavorLibrary") {
id = libs.plugins.template.flavor.library.get().pluginId
implementationClass = "FlavorLibraryConventionPlugin"
}
// Build Types
register("BuildTypeApplication") {
id = libs.plugins.template.buildtype.application.get().pluginId
implementationClass = "BuildTypeApplicationConventionPlugin"
}
register("BuildTypeLibrary") {
id = libs.plugins.template.buildtype.library.get().pluginId
implementationClass = "BuildTypeLibraryConventionPlugin"
}
// Architecture Layers
register("ArchitectureLayerUIArchitectureLayer") {
id = libs.plugins.template.ui.architecture.layer.get().pluginId
implementationClass = "ArchitectureLayerUIConventionPlugin"
}
register("ArchitectureLayerDomainArchitectureLayer") {
id = libs.plugins.template.domain.architecture.layer.get().pluginId
implementationClass = "ArchitectureLayerDomainConventionPlugin"
}
register("ArchitectureLayerDataArchitectureLayer") {
id = libs.plugins.template.data.architecture.layer.get().pluginId
implementationClass = "ArchitectureLayerDataConventionPlugin"
}
}
}
在 dependencies 代码块中声明所有约定插件需要依赖的外部插件。实例中我们引入了 AndroidApplication, AndroidLibrary, Compose 等插件。如果你的项目使用其他插件(如 KSP、Hilt或Firebase),也需要在此处添加相应依赖。同时,这些插件必须在项目根目录的 build.gradle.kts 文件中声明:
kotlin
plugins {
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
}
在 plugins 代码块中,我们注册所有自定义约定插件,这些插件将在各个模块中复用。
重要提示:如果在此处列出了某个约定插件,但实际并未实现它,Gradle 构建过程会直接失败。每个约定插件都必须满足两个条件:
- 在 build-logic 模块中有对应的插件实现类
- 在版本目录文件(libs.versions.toml)中有对应的配置项,确保项目能正确解析和应用该插件
缺少任何一个条件,构建都会因 Gradle 无法找到插件而崩溃。
最后,别忘了在项目根目录的 settings.gradle.kts 文件中引入 build-logic 模块:
pluginManagement {
includeBuild("build-logic") <- Add here
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "Template"
// Application
include(":app")
// Core
include(":core:designsystem")
// Features
/// Auth
include(":feature:auth:data")
include(":feature:auth:domain")
include(":feature:auth:ui")
通过配置提升构建速度
要优化整个项目的构建性能,可以在根目录的 gradle.properties 文件中添加以下配置项:
kt
# Run independent tasks in parallel to speed up multi-module builds
org.gradle.parallel=true
# Reuse outputs from previous builds to avoid re-running tasks unnecessarily
org.gradle.caching=true
# Configure only the modules required for the current build, reducing configuration time
org.gradle.configureondemand=true
# Cache the result of the configuration phase so future builds can skip it entirely
org.gradle.configuration-cache=true
# Allow configuration caching work to run in parallel for even faster setup
org.gradle.configuration-cache.parallel=true
创建 Application 和 Library 的约定插件
首先需要创建的是用于配置应用模块和库模块的约定插件。
大多数项目只有一个应用模块,但使用约定插件可以为未来扩展预留空间------比如你可能需要添加第二个共享核心功能的应用。
而库模块则广泛应用于整个项目,既包括设计系统、网络请求、数据库等核心层模块,也涵盖各个业务功能模块。
Application 约定插件
kt
import com.android.build.api.dsl.ApplicationExtension
import com.example.template.configureAndroid
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.the
class ApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val libs = the<LibrariesForLibs>()
apply(plugin = libs.plugins.android.application.get().pluginId)
apply(plugin = libs.plugins.kotlin.android.get().pluginId)
val extension = extensions.getByType<ApplicationExtension>()
configureAndroid(extension)
}
}
}
Library 约定插件
kt
import com.android.build.api.dsl.LibraryExtension
import com.example.template.configureAndroid
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.the
class LibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val libs = the<LibrariesForLibs>()
apply(plugin = libs.plugins.android.library.get().pluginId)
apply(plugin = libs.plugins.kotlin.android.get().pluginId)
val extension = extensions.getByType<LibraryExtension>()
configureAndroid(extension)
}
}
}
这两个插件都将共享配置委托给 ConfigureAndroid.kt 文件中定义的 configureAndroid 函数。该函数接收对应的通用扩展参数(应用模块对应 ApplicationExtension,库模块对应 LibraryExtension)。
在这个函数中,我们集中管理Android的关键配置:compileSdk、minSdk,以及(仅针对应用模块的)targetSdk。
同时,我们还会调用两个额外的配置函数:来自 ConfigureJava.kt 的 configureJavaAndroid,以及来自 ConfigureKotlin.kt的configureKotlin。
kt
package com.example.template
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
internal fun Project.configureAndroid(
commonExtension: CommonExtension<*, *, *, *, *, *>,
) {
commonExtension.apply {
compileSdk = 36
defaultConfig.minSdk = 24
if (this is ApplicationExtension) {
defaultConfig.targetSdk = 36
}
}
configureJavaAndroid(commonExtension)
configureKotlin<KotlinAndroidProjectExtension>()
}
ConfigureJava.kt 文件包含两个函数:configureJavaAndroid 用于 Android 模块,而 configureJavaJvm 则适用于纯 Kotlin 模块(比如包含用例、仓库接口和数据模型的领域层模块),这些模块不依赖 Android 框架。
kt
package com.example.template
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.kotlin.dsl.configure
private val javaVersion = JavaVersion.VERSION_11
internal fun Project.configureJavaAndroid(commonExtension: CommonExtension<*, *, *, *, *, *>) {
commonExtension.compileOptions {
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
}
}
internal fun Project.configureJavaJvm() {
extensions.configure<JavaPluginExtension> {
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
}
}
最后,ConfigureKotlin.kt 提供了一个专门用于配置 Kotlin 编译器的函数。
完成插件实现后,我们需要在版本目录文件中声明这些约定插件,确保 Gradle 能够正确解析:
toml
template-application = { id = "template.application" }
template-library = { id = "template.library" }
添加到版本目录后,在 build-logic 模块的 build.gradle.kts 文件的 gradlePlugin 代码块中注册这些插件:
kotlin
gradlePlugin {
plugins {
// Android
register("androidApplication") {
id = libs.plugins.template.application.get().pluginId
implementationClass = "ApplicationConventionPlugin"
}
register("androidLibrary") {
id = libs.plugins.template.library.get().pluginId
implementationClass = "LibraryConventionPlugin"
}
.....
}
}
产品风味管理
项目如果需要配置产品风味(product flavors),也需要创建对应的约定插件。和构建类型一样,我们需要为应用模块和库模块分别创建插件,并通过 commonExtension 参数调用共享配置函数。
Application Flavor 约定插件
kt
import com.android.build.api.dsl.ApplicationExtension
import com.example.template.configureFlavor
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
class FlavorApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val extension = extensions.getByType<ApplicationExtension>()
configureFlavor(extension)
}
}
}
Library Flavor 约定插件
kt
import com.android.build.api.dsl.LibraryExtension
import com.example.template.configureFlavor
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
class FlavorLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val extension = extensions.getByType<LibraryExtension>()
configureFlavor(extension)
}
}
}
Flavors 公共配置
kt
package com.example.template
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.Project
private data class Dimension(val name: String, val values: List<String>)
private val environmentDimension = Dimension(
name = "environment",
values = listOf("dev", "prod"),
)
internal fun Project.configureFlavor(
commonExtension: CommonExtension<*, *, *, *, *, *>,
) {
commonExtension.apply {
flavorDimensions += environmentDimension.name
productFlavors {
environmentDimension.values.forEach { value ->
register(value) {
dimension = environmentDimension.name
}
}
}
}
}
Compose 配置
接下来,我们创建Compose相关的约定插件。同样的,需要两个插件(应用模块和库模块各一个),再加上一个共享的通用配置函数。
Application Compose 约定插件
在这个插件中,我们添加了Compose Activity所需的依赖。这些依赖没有放在库插件中,因为我们遵循单Activity架构原则。
注:如果你的项目需要在库模块中使用Activity组件,可以将这些依赖移到通用配置中。
kt
import com.android.build.api.dsl.ApplicationExtension
import com.example.template.configureCompose
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.the
class ComposeApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val libs = the<LibrariesForLibs>()
apply(plugin = libs.plugins.kotlin.compose.get().pluginId)
val extension = extensions.getByType<ApplicationExtension>()
configureCompose(extension)
dependencies {
"implementation"(libs.androidx.activity.compose)
}
}
}
}
Library Compose 约定插件
kt
import com.android.build.api.dsl.LibraryExtension
import com.example.template.configureCompose
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.the
class ComposeLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val libs = the<LibrariesForLibs>()
apply(plugin = libs.plugins.kotlin.compose.get().pluginId)
val extension = extensions.getByType<LibraryExtension>()
configureCompose(extension)
}
}
}
Compose 通用配置
通用配置负责处理 Compose 的共享设置,包括 Compose BOM 以及从版本目录中引入的其他依赖:
kt
package com.example.template
import com.android.build.api.dsl.CommonExtension
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.the
internal fun Project.configureCompose(
commonExtension: CommonExtension<*, *, *, *, *, *>,
) {
commonExtension.apply {
val libs = the<LibrariesForLibs>()
buildFeatures {
compose = true
}
dependencies {
"implementation"(platform(libs.androidx.compose.bom))
"implementation"(libs.androidx.compose.ui)
"implementation"(libs.androidx.compose.ui.graphics)
"implementation"(libs.androidx.compose.ui.tooling.preview)
"implementation"(libs.androidx.compose.material3)
"androidTestImplementation"(platform(libs.androidx.compose.bom))
"androidTestImplementation"(libs.androidx.compose.ui.test.junit4)
"debugImplementation"(libs.androidx.compose.ui.tooling)
"debugImplementation"(libs.androidx.compose.ui.test.manifest)
}
}
}
Koin 依赖注入配置
接下来,我们用Koin配置依赖注入。这里我们创建两个约定插件,但划分依据不是应用模块或库模块,而是模块的类型:
- Android模块
- 核心(纯Kotlin)模块
这里没有通用配置函数,因为我们只为每种模块类型添加特定的依赖。
Koin Android 约定插件
kt
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.the
class KoinAndroidConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val libs = the<LibrariesForLibs>()
dependencies {
"implementation"(project.dependencies.platform(libs.koin.bom))
"implementation"(libs.koin.android)
"testImplementation"(libs.koin.android.test)
"testImplementation"(libs.koin.junit4)
}
}
}
}
Koin Coin 约定插件
kt
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.the
class KoinCoreConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val libs = the<LibrariesForLibs>()
dependencies {
"implementation"(project.dependencies.platform(libs.koin.bom))
"implementation"(libs.koin.core)
"testImplementation"(libs.koin.test)
"testImplementation"(libs.koin.junit4)
}
}
}
}
版本目录 (Version Catalog
)
别忘了在版本目录文件(libs.versions.toml)中声明所有约定插件需要的依赖。
[versions]
agp = "8.13.0"
kotlin = "2.2.21"
kotlin-serialization-json = "1.9.0"
coreKtx = "1.17.0"
junit = "4.13.2"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.10.0"
composeActivity = "1.12.0"
composeBom = "2025.11.01"
ksp = "2.2.20-2.0.4"
koin-bom = "4.1.1"
ktor-bom = "3.3.2"
navigation = "2.9.6"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
# Kotlin
kotlin-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlin-serialization-json" }
# Compose
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "composeActivity" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
# Koin
koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koin-bom" }
koin-core = { module = "io.insert-koin:koin-core" }
koin-android = { module = "io.insert-koin:koin-android" }
koin-android-compose = { module = "io.insert-koin:koin-androidx-compose" }
koin-android-compose-navigation = { module = "io.insert-koin:koin-androidx-compose-navigation" }
koin-test = { module = "io.insert-koin:koin-test" }
koin-android-test = { module = "io.insert-koin:koin-android-test" }
koin-junit4 = { module = "io.insert-koin:koin-test-junit4" }
# Ktor
ktor-bom = { module = "io.ktor:ktor-bom", version.ref = "ktor-bom" }
ktor-core = { module = "io.ktor:ktor-client-core" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging" }
ktor-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation" }
ktor-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json" }
# Dependencies of the included build-logic
android-gradleApiPlugin = { group = "com.android.tools.build", name = "gradle-api", version.ref = "agp" }
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]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
# Plugins included build-logic
template-application = { id = "template.application" }
template-library = { id = "template.library" }
template-jvm = { id = "template.jvm" }
template-kotlin-serialization = { id = "template.kotlin.serialization" }
template-compose-application = { id = "template.compose.application" }
template-compose-library = { id = "template.compose.library" }
template-koin-core = { id = "template.koin.core" }
template-koin-android = { id = "template.koin.android" }
template-flavor-application = { id = "template.flavor.application" }
template-flavor-library = { id = "template.flavor.library" }
template-buildtype-application = { id = "template.buildtype.application" }
template-buildtype-library = { id = "template.buildtype.library" }
template-ui-architecture-layer = { id = "template.ui.architecture.layer" }
template-data-architecture-layer = { id = "template.data.architecture.layer" }
template-domain-architecture-layer = { id = "template.domain.architecture.layer" }
在模块中应用插件
所有约定插件都定义完成后,就可以在应用模块中使用了。
例如,我们可以将原来冗长的配置:
kt
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
}
android {
namespace = "com.example.template"
compileSdk = 36
defaultConfig {
applicationId = "com.example.template"
minSdk = 24
targetSdk = 36
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.tooling)
debugImplementation(libs.androidx.compose.ui.test.manifest)
}
(示例中省略了风味和 Kotlin 选项的配置,实际的 build.gradle.kts 文件会更加庞大)
简化为使用约定插件的简洁配置:
kt
plugins {
alias(libs.plugins.template.application)
alias(libs.plugins.template.compose.application)
alias(libs.plugins.template.flavor.application)
alias(libs.plugins.template.buildtype.application)
alias(libs.plugins.template.koin.android)
}
android {
namespace = "com.example.template"
defaultConfig {
applicationId = "com.example.template"
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
}
这种方式不仅实现了构建逻辑的集中管理,减少了代码重复,还让后续跨模块的更新维护变得异常轻松。