如何在Gradle中的buildType上添加条件afterEvaluate

Ali*_*lix 1 android gradle android-gradle-plugin

我在build.gradle文件的末尾有这个代码:

         project.afterEvaluate {

            // If you add/change build types, you have to add to/change
            // these task names.
            mergeDebugAssets.dependsOn project.tasks.getByName('downloadLicenses')
            mergeReleaseAssets.dependsOn project.tasks.getByName('downloadLicenses')

        }
Run Code Online (Sandbox Code Playgroud)

请参阅:将生成的第三方许可证复制到资产以获取完整代码

这曾经工作正常(无论设置了哪个buildType),但如果将我的依赖项更新到最新版本,则会触发异常(使用buildType ='debug'构建时):

Could not get unknown property 'mergeReleaseAssets' for project ':application'

我的想法是,可能将此块拆分为两个并将它们置于buildTypes配置下.这不起作用,因为它试图无论如何评估代码并崩溃.

有任何想法吗?

更新1:根本原因? https://code.google.com/p/android/issues/detail?id=219732

更新2:一个可怕的解决方法:

try {
    mergeDebugAssets.dependsOn project.tasks.getByName('downloadLicenses')
} catch (Exception e) {
    // Expected when building variant Release
}
try {
    mergeReleaseAssets.dependsOn project.tasks.getByName('downloadLicenses')
} catch (Exception e) {
    // Expected when building variant Debug
}
Run Code Online (Sandbox Code Playgroud)

Xar*_*rgs 6

您在引用发布任务时出错的原因afterEvaluate可能是因为Android Studio的即时运行功能使用特殊的Android Gradle插件功能来构建调试应用程序变体.这意味着只创建了调试任务,因此在引用它们时无法找到发布任务的原因.

有几种方法可以解决这个问题:

  1. 使用字符串按名称搜索依赖任务.如果Android构建系统将来更改任务名称,则您的其他构建规则将无法运行,但您可能甚至都没有注意到.

  2. 要确定是否存在发布任务,请检查是否存在名称将来不太可能更改的任务.也许assembleRelease适合这个法案.

  3. 要确定是否存在发布任务,请检查发布应用程序变体是否使用以下内容构建:

    project.afterEvaluate {
        if (!android.applicationVariants.matching { it.buildType.name == 'release' }.isEmpty()) {
            mergeReleaseAssets.dependsOn project.tasks.getByName('downloadLicenses')
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

最后一个选项看起来很糟糕,但希望如果Android构建系统任务名称在将来发生变化,它将会失败.


Iva*_*lov 5

在 debug buildType 的情况下出现异常的原因是因为mergeReleaseAssets没有创建任务。您可以改为执行以下操作:

project.tasks.findByName('mergeReleaseAssets')?.dependsOn project.tasks.getByName('downloadLicenses')
Run Code Online (Sandbox Code Playgroud)

甚至省略project

tasks.findByName('mergeReleaseAssets')?.dependsOn tasks.getByName('downloadLicenses')
Run Code Online (Sandbox Code Playgroud)

这在可空返回类型上使用安全导航运算符,因此它比 try/catch 解决方法更清晰。