Android杂谈之大项目插件统一管理

想一想,如果你要构建一个大点的工程,有多个项目,有多个模块,可能有插件化组件化,每个子模块下重复的配置是不是非常的多?如何规避多人之间使用不同的依赖版本?

可以利用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)

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容