简化Android构建

270 阅读3分钟

了解如何创建和使用自定义 Gradle 插件

原文:medium.com/@sridhar-sp…

什么是约定插件

约定插件是一种组织 Gradle 文件的结构化方法,可作为 Gradle 模块中的一个插件使用。

优点

可重复使用: 插件可在多个 Gradle 模块中重复使用,从而提高一致性和效率。

易于维护: 复杂的构建逻辑可通过扩展或组合其他构建逻辑来开发,并可封装到专用插件(如 ArtifactDeploymentPlugin、AndroidLibraryPlugin 和 AndroidComposePlugin 等)中,以方便使用。

易于使用: 通过应用插件,用户可以轻松地为其构建流程添加新功能,而无需再次从头开始编写复杂的代码。

可测试的构建逻辑: 可使用 TestKit 测试构建逻辑,以验证其行为。(尚未尝试)

怎么添加约定插件

第一步:创建 build-logic 目录

  1. 创建一个单独的 build-logic 文件夹来整理你的约定插件代码,并将其与其他项目代码分开。
  2. 在根目录下,创建一个 settings.gradle.kts 文件,内容如下:
dependencyResolutionManagement {  
  
repositories {  
    google()  
    mavenCentral()  
}  
  
versionCatalogs {  
    create("libs") {  
        from(files("../gradle/libs.versions.toml")) // Create this file if not present.  
        }  
    }  
}  
  
rootProject.name = "build-logic"  
// include(":convention") // Enable this line only after step 2

在项目的 settings.gradle.kts 内,将 includeBuild(“build-logic”) 添加到 pluginManagement 块中。

pluginManagement {  
  
    includeBuild("build-logic") // Include the build-logic  

    repositories {  
        // ...  
        gradlePluginPortal()  
    }  
}  
  
// ...

第二步:创建构建约定模块

  1. 在 build-logic 下添加一个新的 Java/Kotlin 模块,并将其命名为 convention 。在此示例中,包名称为 com.droidstarter.convention 。
  2. 确保删除根 settings.gradle.kts 文件中任何类似 include(“:build-logic:convention”) 的条目(当创建新模块时,Studio 会自动添加此条目)。
  3. 将 convention 模块中的脚本替换为:
plugins {  
    `kotlin-dsl`  
}  
  
group = "com.example.buildlogic" // Package name for the our plugins  
  
java {  
    sourceCompatibility = JavaVersion.VERSION_17  
    targetCompatibility = JavaVersion.VERSION_17  
}  
  
dependencies {  
    compileOnly(libs.android.gradlePlugin)  
    compileOnly(libs.kotlin.gradlePlugin)  
}  
  
gradlePlugin {  
    plugins {  
    // Will add in next step  
    }  
}

将以下依赖项添加到 libs.versions.toml :

[versions]  
androidGradlePlugin = "8.0.2" # use latest version  
kotlin = "1.9.22" # use latest version  
  
[libraries]  
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }  
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }

在 build-logic 模块的 settings.gradle.kts 文件中添加 include(“:convention”) ,然后执行 Gradle 同步。

第三步:创建自定义 Gradle 约定插件

  1. 首先,设置一个名为 AndroidApplicationComposeConventionPlugin 的基本约定插件。此插件将集中设置一个使用 Jetpack Compose 的 Android 项目所需的所有构建配置。
  2. 使用 Plugin<Project> 来定义和应用自定义配置。
class AndroidApplicationComposeConventionPlugin : Plugin<Project> {  
    override fun apply(target: Project) {  
        println("*** AndroidApplicationComposeConventionPlugin invoked ***")  
        // Additional configuration here...  
    }  
}
  1. 在 build-logic 的 build.gradle.kts 中注册插件,使其可在其他模块中使用:
plugins {  
    `kotlin-dsl`  
}  
  
// ...  
  
gradlePlugin {  
    plugins {  
        create("androidApplicationCompose") {  
            id = "com.example.convention.application.compose" // This is the id we used to resolve our plugin.  
            implementationClass = "com.example.convention.AndroidApplicationComposeConventionPlugin"  
        }  
    }  
}
  1. 将新创建的插件应用到你的 app 模块或任何 Android 应用模块。
plugins {  
    id("com.example.convention.application.compose")  
}
  1. 执行 Gradle 同步,你现在应该在构建窗口中看到以下日志:**** AndroidApplicationComposeConventionPlugin invoked ****

第四步:为使用 Jetpack Compose 构建逻辑的 Android 应用配置插件

  1. 在你的约定插件中应用 Android 和 Kotlin 插件,这样当该插件被应用时,这些插件会自动被包含进来。这使你可以从应用模块的 build.gradle.kts 中移除它们。
class AndroidApplicationComposeConventionPlugin : Plugin<Project> {  
    override fun apply(target: Project) {  
        println("*** AndroidApplicationComposeConventionPlugin invoked ***")  
        with(target) {  
            with(pluginManager) {  
                apply("com.android.application") // Include android application plugin  
                apply("org.jetbrains.kotlin.android") // Ensure project build.gradle declared this plugin  
            }  
        }  
    }  
}
  1. 配置常见的设置,如 compileSdk , minSdk , targetSdk , sourceCompatibility , targetCompatibility , 和 kotlinJvmTarget 
  2. 设置 Jetpack Compose 配置,包括启用 Compose 功能和添加必要的依赖项。
class AndroidApplicationComposeConventionPlugin : Plugin<Project> {  
    override fun apply(target: Project) { 
        with(target) {  

            apply("com.android.application")  
            apply("org.jetbrains.kotlin.android") // Ensure project build.gradle declared this plugin  

            val extensions = extensions.getByType<ApplicationExtension>()
            configureAndroidCompose(extensions)
        }  
    }  
}  
  
  
internal fun Project.configureAndroidCompose(commonExtension: CommonExtension<*, *, *, *, *, *>) {  
    val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")  
  
    commonExtension.apply {  
        compileSdk = 36

        defaultConfig {  
            minSdk = 29  
        }  

        compileOptions {  
            sourceCompatibility = JavaVersion.VERSION_17 
            targetCompatibility = JavaVersion.VERSION_17  
        }  

        buildFeatures {  
            compose = true  
        }  

        composeOptions {  
        // Add androidxComposeCompiler in toml  
            kotlinCompilerExtensionVersion = libs.findVersion("androidxComposeCompiler").get().toString()  
        }
        
        dependencies {
            val bom = libs.findLibrary("androidx-compose-bom").get()
            add("implementation", platform(bom))

            listOf(
                "androidx.core.ktx",
                "androidx.lifecycle.runtime.ktx",
                "androidx.activity.compose",
                "androidx.ui",
                "androidx.ui.graphics",
                "androidx.ui.tooling.preview",
                "androidx.material3",
//                "material.icons.extended"
            ).forEach { alias ->
                add("implementation", libs.findLibrary(alias).get())
            }

            add("testImplementation", libs.findLibrary("junit").get())
            add("androidTestImplementation", libs.findLibrary("androidx.junit").get())
            add("androidTestImplementation", libs.findLibrary("androidx.espresso.core").get())
            add("androidTestImplementation", platform(bom))
            add("androidTestImplementation", libs.findLibrary("androidx.ui.test.junit4").get())
            add("androidTestImplementation", libs.findLibrary("androidx.ui.tooling").get())
            add("androidTestImplementation", libs.findLibrary("androidx.ui.test.manifest").get())
        }
    }  

    tasks.withType<KotlinCompile>().configureEach {  
        kotlinOptions {  
            jvmTarget.set(JvmTarget.JVM_17)
        }  
    }  
}
  1. 将以下依赖项添加到 libs.versions.toml :
[versions]
androidxComposeCompiler = "1.5.10" # use latest version
androidxComposeBom = "2024.02.01" # use latest version

[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" }