何时在 Gradle 插件中应用自定义 Android 扩展?
When to apply a custom Android extension within a Gradle plugin?
我正在尝试编写一个 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)"
}
}
}
}
...和我的自定义扩展 class
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 tasks have already been created.
This happens when calling android.applicationVariants, android.libraryVariants or android.testVariants.
Once these methods are called, it is not possible to continue configuring the model.
您遇到的问题如下:
想象一下 Gradle 从上到下遍历您的构建脚本。
它会找到您的插件并执行 apply
函数。
在该函数中,您创建 productFlavor
并 应用 值(versionName
到 9.9.9
来自您的 extension ).
apply
方法 returns 和 Gradle 更深入构建脚本。
它会找到您的扩展设置,将值设置为扩展,然后...继续“扫描”构建脚本。
那是它。
你需要“东西”(比如观察者)来告诉 AGP productFlavor
的 versionName
需要更新 只要扩展的值设置.
Gradle前段时间介绍过“Lazy configuration”。 See the docs here。
这样就有可能(以 Gradle 方式)。但是 ProductFlavor.versionName
应该是 Property<String>
类型。但这不是 - 今天的状态。
无论如何。我找到了 "workaround"(我不确定这是否是解决方法或就 Gradle 的工作方式而言是否可以接受):
您可以将 ProductFlavor
class 作为扩展的构造函数参数,并在扩展 属性 设置后立即更新值:
您的插件:
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)"
}
}
我正在尝试编写一个 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)"
}
}
}
}
...和我的自定义扩展 class
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 tasks have already been created.
This happens when calling android.applicationVariants, android.libraryVariants or android.testVariants.
Once these methods are called, it is not possible to continue configuring the model.
您遇到的问题如下:
想象一下 Gradle 从上到下遍历您的构建脚本。
它会找到您的插件并执行 apply
函数。
在该函数中,您创建 productFlavor
并 应用 值(versionName
到 9.9.9
来自您的 extension ).
apply
方法 returns 和 Gradle 更深入构建脚本。
它会找到您的扩展设置,将值设置为扩展,然后...继续“扫描”构建脚本。
那是它。
你需要“东西”(比如观察者)来告诉 AGP productFlavor
的 versionName
需要更新 只要扩展的值设置.
Gradle前段时间介绍过“Lazy configuration”。 See the docs here。
这样就有可能(以 Gradle 方式)。但是 ProductFlavor.versionName
应该是 Property<String>
类型。但这不是 - 今天的状态。
无论如何。我找到了 "workaround"(我不确定这是否是解决方法或就 Gradle 的工作方式而言是否可以接受):
您可以将 ProductFlavor
class 作为扩展的构造函数参数,并在扩展 属性 设置后立即更新值:
您的插件:
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)"
}
}