想一想,如果你要构建一个大点的工程,有多个项目,有多个模块,可能有插件化组件化,每个子模块下重复的配置是不是非常的多?如何规避多人之间使用不同的依赖版本?
可以利用maven将通用的配置做成插件发布,然后在所有项目里使用你自己的插件应该就能解决这个问题。新建个Pluging工程,settings.gradle.kts配置如下:
dependencyResolutionManagement{
repositories{
google()
mavenCentral()
}
versionCatalogs{
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name ="gradle-pluging"
include(":pluging")
在编写build.gradle.kts将通用的插件与配置注册并发布到maven,配置如下:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
`kotlin-dsl`
`ivy-publish`
}
group ="com.xxx.plugin" //group自己定义即可
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
tasks.withType<KotlinCompile>().configureEach{
kotlinOptions{
jvmTarget = JavaVersion.VERSION_17.toString()
}
} //jdk版本根据实际需要选择
dependencies {
compileOnly(libs.android.gradlePlugin)
compileOnly(libs.kotlin.gradlePlugin)
compileOnly(libs.ksp.gradlePlugin)
} //使用kapt或ksp根据实际需要选择
gradlePlugin {
plugins{ //此处举几个最常用的例子 application, library, compose支持, 也可以对其它依赖注册,比如出海应用相关的google组件firebase.bom, analytics.ktx, crashlytics.ktx, crashlytics.ndk, google.location, goole.map, goole.map.ktx, google.pay 等 ,网络相关的okhttp , okhttp.logging, okhttp.urlconnection, retrofit, moshi, moshi.kotlin, converter.moshi, //moshi可用gson或jackson替换
register("Application") {
id ="xxx.android.application" //id自己定义即可,为plugins {} 里引用的id
implementationClass ="ApplicationPlugin"
}
register("Library") {
id ="xxx.android.library"
implementationClass ="LibraryPlugin"
}
register("Compose") {
id ="xxx.android.compose"
implementationClass ="ComposePlugin"
}
}
}
publishing {
publications{
create<IvyPublication>("ivy") {
organisation ="com.xxx.plugin" //组织自己定义
module ="gradle-pluging"
revision ="1.0"
descriptor.status ="milestone"
descriptor.branch ="develop"
descriptor.extraInfo("http://plugin.xxx","dsl","plugin")
from(components["kotlin"])
}
}
}
定义完就到Pluginp实现了,继承Pluginp实现apply方法即可,拿ApplicationPluging来说:
class ApplicationPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.application") // LibraryPlugin换成 com.android.library
apply("org.jetbrains.kotlin.android")
}
extensions.configure<ApplicationExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk =34
}
}
}
}
这里的configureKotlinAndroidj是通用方法因为在Library插件实现时也需要调用
internal fun Project.configureKotlinAndroid(
commonExtension: CommonExtension<*, *, *, *, *>,
) {
commonExtension.apply {
compileSdk =34
defaultConfig{
minSdk =31
vectorDrawables.useSupportLibrary =true
}
compileOptions{
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
} //jdk版本根据实际需要选择
viewBinding{
enable =true
}
dataBinding{
enable =true
}
buildFeatures{
aidl =true
buildConfig =true
}
}
tasks.withType<KotlinCompile>().configureEach{
kotlinOptions{
jvmTarget = JavaVersion.VERSION_17.toString()
val warningsAsErrors: String?by project
allWarningsAsErrors = warningsAsErrors.toBoolean()
freeCompilerArgs =freeCompilerArgs +listOf(
"-opt-in=kotlin.RequiresOptIn",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlin.Experimental",
)
}
}
} //通用的配置可以自己添加
ComposePlugin 配置如下:
class ComposePlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("com.android.application")
val libs =extensions.getByType<VersionCatalogsExtension>().named("libs")
extensions.getByType<ApplicationExtension>().apply {
buildFeatures{
compose =true
}
composeOptions{
kotlinCompilerExtensionVersion =
libs.findVersion("composeCompiler").get().toString()
}
dependencies {
val bom = libs.findLibrary("compose.bom").get()
add("implementation", platform(bom))
add("implementation", libs.findLibrary("compose.ui").get())
add("implementation", libs.findLibrary("compose.ui.preview").get())
add("implementation", libs.findLibrary("compose.runtime").get())
add("implementation", libs.findLibrary("compose.animation").get())
add("implementation", libs.findLibrary("compose.material3").get())
add("implementation", libs.findLibrary("compose.foundation").get())
add("implementation", libs.findLibrary("compose.foundation.layout").get())
}
}
tasks.withType<KotlinCompile>().configureEach{
kotlinOptions{
freeCompilerArgs =freeCompilerArgs +buildComposeMetricsParameters()
}
}
}
}
private fun Project.buildComposeMetricsParameters(): List<String> {
val metricParameters =mutableListOf<String>()
val enableMetricsProvider =project.providers.gradleProperty("enableComposeCompilerMetrics")
val enableMetrics =(enableMetricsProvider.orNull =="true")
if (enableMetrics) {
val metricsFolder = File(project.buildDir,"compose-metrics")
metricParameters.add("-P")
metricParameters.add(
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath
)
}
val enableReportsProvider =project.providers.gradleProperty("enableComposeCompilerReports")
val enableReports =(enableReportsProvider.orNull =="true")
if (enableReports) {
val reportsFolder = File(project.buildDir,"compose-reports")
metricParameters.add("-P")
metricParameters.add(
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath
)
}
return metricParameters.toList()
}
}
gradle版本gradle-8.5, AGP版本 "8.2.2"
libs.versions.toml里的[versions],[libraries], [plugins] 自己添加
发布后在项目中引用:
plugins {
id("xxx.android.application")
}
android {
namespace ="com.xxx.xxx" //通用配置里配置过的都不必再写,只需要定义渠道签名等信息即可
}
dependencies { //这些也可做成通用插件
implementation(libs.core.ktx)
implementation(libs.appcompat)
}