具有依赖关系的Android Studio自定义gradle任务 - “无法获取未知属性”

时间:2017-06-01 02:17:27

标签: android android-studio gradle android-gradle

我正在使用一个提供gradle任务的库来将构建上传到HockeyApp(https://github.com/x2on/gradle-hockeyapp-plugin)。我认为它具体做的并不重要,只是它创造了任务。我可以运行这些任务没问题。我想创建一个任务来同时运行其中几个自定义任务。上传任务的名称类似于upload[BuildVariant]ToHockeyApp,并为每个构建变体创建了一个。我在项目级gradle文件中android中定义的自定义任务如下所示:

task uploadLegacyReleaseToHockeyApp(dependsOn:
            uploadVariant1ReleaseToHockeyApp,
            uploadVariant2ReleaseToHockeyApp,
            // etc
      ){}

同步gradle文件时,出现此错误:

Error:(89, 0) Could not get unknown property 'uploadVariant1ReleaseToHockeyApp' for object of type com.android.build.gradle.AppExtension.

我已经三次检查没有拼写错误,错误消息中的任务实际存在。我做错了什么,或者是否无法对像这样动态生成的任务编写依赖关系?我真的不知道插件是如何工作的,但它创建了自己的任务组,其中包含自动生成的任务。

更新根据lukegv的回答:

如果我使用dependsOn方法,我会收到此错误:Error:(90, 0) Could not get unknown property 'uploadVariant1ToHockeyApp' for task ':app:uploadLegacyReleaseToHockeyApp' of type org.gradle.api.DefaultTask.

使用构造函数:

task uploadLegacyReleaseToHockeyApp(dependsOn:
            'uploadVariant1ToHockeyApp',
            'uploadVariant2ToHockeyApp',
            // etc

我得到了这个:Could not find method uploadLegacyReleaseToHockeyApp() for arguments [{dependsOn=uploadVariant1ToHockeyApp}, uploadVariant2ToHockeyApp,...

请注意,第一项是大括号,其余项不是。

如果我将所有任务名称放在一个字符串中,它会成功同步构建文件,但字符串会被解释为单个任务名称,因此运行它会失败。

2 个答案:

答案 0 :(得分:3)

Gradle区分配置阶段执行阶段。在配置阶段中,Gradle评估(通过执行)整个构建脚本,然后构建任务依赖关系树。在执行阶段中,Gradle执行通过命令行及其依赖项指定的任务。

由于可以在整个构建脚本中添加或定义变体等内容,因此生成的任务通常在配置阶段的末尾创建,因此它们不能作为属性在配置期间的Project范围。

但是,您可以通过将任务名称指定为String来定义任务依赖关系。这样,在构建依赖关系树之后,将注册依赖项并在配置阶段之后使用随后生成的任务。

作为一个例子:

task t1 {
    dependsOn t2        // this fails
    dependsOn 't2'      // this works, even if t2 does not exist right now
}

afterEvaluate {
    task t2 {}
}

要解决您的特定问题,请将您的任务依赖项指定为包含任务名称的字符串:

task uploadLegacyReleaseToHockeyApp {
    dependsOn 'uploadVariant1ReleaseToHockeyApp'
    dependsOn 'uploadVariant2ReleaseToHockeyApp'
}

我在构造函数中使用dependsOn方法而不是dependsOn映射键,因为我认为它更优雅,但是您也可以编辑代码以使用字符串列表:

task uploadLegacyReleaseToHockeyApp(dependsOn: ['uploadVariant1ReleaseToHockeyApp', 'uploadVariant2ReleaseToHockeyApp']) {
    // configuration
}

答案 1 :(得分:1)

我得到了它的工作,经过我在构造函数中找到dependsOn的进一步搜索后,它需要是一个数组,而不仅仅是一个字符串列表:

task taskName(dependsOn:
            ['otherTask1','otherTask2']){}

我不知道dependsOn方法失败的原因,但我有一些有效的方法。