【问题标题】:When to apply a custom Android extension within a Gradle plugin?何时在 Gradle 插件中应用自定义 Android 扩展?
【发布时间】:2019-12-18 23:29:14
【问题描述】:

我正在尝试编写一个 Gradle 插件,它封装了我项目中 android { ... } 块的常见配置设置。一个示例是添加dev 产品风味:

develop {
    applicationIdSuffix ".dev"
    versionCode 100000
    versionName appVersionName + " (development)"
}

在 Gradle 插件中,我按如下方式应用此配置:

class MyAndroidPlugin : Plugin<Project> {

    private lateinit var myExtension: MyExtension

    override fun apply(project: Project) {

        myExtension = project.extensions.create(MyExtension.NAME, MyExtension::class.java)

        val androidExtension = extensions.findByName("android") as AppExtension
        androidExtension.productFlavors.create("dev") {
            with(project) {
                applicationIdSuffix = ".dev"
                versionCode = 100000
                versionName = "${myExtension.appVersionName} (development)"
            }
        }
    }
}

...和我的自定义扩展类

open class MyExtension {

    companion object {
        const val NAME = "myplugin"
    }

    var appVersionName: String? = "9.9.9"

}

当我在一个 Android 项目中配置我的插件时...

apply plugin: "com.android.application"
apply plugin: "com.example.android.gradle"

android {
    ...
}

myplugin {
    appVersionName = "3.2.1"
}

...然后versionName 没有被修改 - 它仍然是“9.9.9”。似乎“3.2.1”值应用得不够早。我试过project.afterEvaluate { ... } 导致以下错误:

Android 任务已创建。
调用 android.applicationVariants、android.libraryVariants 或 android.testVariants 时会发生这种情况。
一旦调用了这些方法,就无法继续配置模型。

【问题讨论】:

  • 我只是猜测,尝试更改“versionName”命名,而不是${myExtension.appVersionName} => ${myExtension.versionName}
  • @mmmatey 我的错。我修复了变量名。谢谢。

标签: android gradle android-gradle-plugin gradle-plugin


【解决方案1】:

您面临的问题如下:

想象一下 Gradle 从上到下遍历您的构建脚本。 它会找到您的插件并执行apply 函数。 在该函数中,您创建 productFlavor应用 值(versionName9.9.9 来自您的 extension)。 apply 方法返回,Gradle 进一步深入构建脚本。 它会找到您的扩展设置,将值设置为扩展并...继续“扫描”构建脚本。

那就是它。

您需要“某种东西”(例如观察者),它告诉 AGP productFlavorversionName 需要在设置扩展值后立即更新

Gradle 前段时间引入了“懒惰配置”。 See the docs here。 这样就有可能(以 Gradle 方式)。但是ProductFlavor.versionName 应该是Property&lt;String&gt; 类型。但这不是今天的状态。

无论如何。我找到了一种“解决方法”(我不确定这是否是一种解决方法或就 Gradle 的工作方式而言是否可以接受):

您可以将 ProductFlavor 类作为构造函数参数添加到您的扩展中,并在扩展属性设置后立即更新值:

您的插件:

override fun apply(project: Project) {
    val androidExtension = project.extensions.findByName("android") as AppExtension
    val flavor = androidExtension.productFlavors.create("dev")

    val myExtension = project.extensions.create(MyExtension.NAME, MyExtension::class.java, flavor)
}

扩展名:

open class MyExtension(
    private val productFlavor: ProductFlavor
) {

    companion object {
        const val NAME = "myplugin"
    }

    var versionName: String? = "9.9.9"
        set(value) {
            productFlavor.applicationIdSuffix = ".dev"
            productFlavor.dimension = "nuts"
            productFlavor.versionCode = 100000
            productFlavor.versionName = "$value (development)"
        }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 2015-11-11
    • 2021-06-05
    相关资源
    最近更新 更多