【问题标题】:Run grade tasks inside a task without dependsOn在不依赖于的任务中运行评分任务
【发布时间】:2018-11-25 00:48:26
【问题描述】:

假设我已经从 cmd 行执行了一组任务并且它可以工作:

gradle processReleaseManifest compileReleaseSources run assembleRelease

这里运行的是我定义的任务。

所以我的要求是我需要创建一个执行上述4个任务的任务, 就像说新任务 abc,以相同的顺序运行上述任务,

我知道在这种情况下我不能使用dependsOn,因为在它显示的构建gradle中使用processReleaseManifest compileReleaseSource时,

无法为 org.gradle.api.Project 类型的项目 ':app' 获取未知属性 'assembleRelease'

那么解决办法是什么?

【问题讨论】:

    标签: android android-studio gradle groovy android-gradle-plugin


    【解决方案1】:

    您可以,因为@lu.koerfer 的回答表明使用dependsOn 列表中的字符串来引用构建文件中进一步定义的任务。

    换句话说,这是可行的:

    task foo {}
    task bar(dependsOn: [foo]) {}
    

    这也有效:

    task bar(dependsOn: ['foo']) {}
    task foo {} 
    

    现在,要让任务按照您想要的顺序运行,事情并不是那么简单。 dependsOn 属性仅告诉任务在任务本身运行之前需要运行哪些任务。它确实 not 告诉 gradle 按照dependsOn 子句中定义的顺序运行任务。

    一个例子:

    task one {}
    task two {} 
    task three {} 
    task run(dependsOn: [one, two, three]) {}
    

    运行时产生以下输出:

    ~> gradle run
    :one UP-TO-DATE
    :three UP-TO-DATE
    :two UP-TO-DATE
    :run UP-TO-DATE
    
    BUILD SUCCESSFUL
    

    ...请注意,我们没有按照onetwothreerun 的顺序运行。

    换句话说,命令行调用强制任务按照定义的顺序运行,而dependsOn 是一个集合并且没有顺序。

    有几种方法可以让任务按照您想要的顺序运行。一种是定义任务的依赖关系(这可能是常见的路径):

    task one {}
    task two(dependsOn: ['one']) {} 
    task three(dependsOn: ['two']) {} 
    task run(dependsOn: [one, two, three]) {}
    

    导致:

    ~> gradle run
    :one UP-TO-DATE
    :two UP-TO-DATE
    :three UP-TO-DATE
    :run UP-TO-DATE
    
    BUILD SUCCESSFUL
    

    另外一种是使用gradle后面版本中添加的task ordering constructs

    此外,如果您需要将任务依赖项添加到在文件前面某处定义的任务中,您可以通过以下方式进行:

    task foo {}
    someTaskDefinedFurtherUp.dependsOn 'foo'
    

    将任务foo 添加到someTaskDefinedFurtherUp 的依赖项中。

    【讨论】:

      【解决方案2】:

      您需要将任务名称作为字符串传递给dependsOn 方法,因为在您调用它时,尚未创建任务对象。但是,如果您传递字符串,任务名称将在稍后进行评估:

      task abc {
          dependsOn 'processReleaseManifest', 'compileReleaseSources', 'run', 'assembleRelease'
      }
      

      【讨论】:

      • 看我有,processReleaseManifest compileReleaseSources 运行 assembleRelease 要运行的 4 个任务,所以如果我执行你的步骤,它只会 assembleRelease。我不能让 assembleRelease 依赖某些东西,它会弹出我在问题中提到的错误
      • 那么您应该可以通过dependsOn将所有这些任务添加到另一个任务的任务依赖项中。
      • 我该怎么做?能发个我能看懂的代码sn-p吗
      • 它没有按顺序运行,所以会产生错误的结果
      • 有什么办法像,task run(type:JavaExec){ executable 'java' main="-jar" args "LogObfuscator.jar",'/release/com','s/cloud /' doLast{ println "successful" } } 这里我们调用java的权限同样可以make executable for gradle
      【解决方案3】:

      由于通过dependsOnmustRunAfter / shouldRunAfter 指定任务依赖关系和排序可能但非常复杂,我将提出另一种可能的解决方案:

      您可以从 Gradle 调用 Gradle 并以与通过命令行相同的方式指定任务:

      task abc(type: GradleBuild) {
          tasks = ['processReleaseManifest', 'compileReleaseSources', 'run', 'assembleRelease']
      }
      

      这将从当前构建中再次调用 Gradle 并按指定顺序执行任务。

      【讨论】:

      • 是的,这清除了它!在关闭线程之前我需要更多答案,主要概念是运行过程更改类文件中的内容。所以当我运行这个 abc 时,我得到了修改后的 apk。因此,与其明确地做 gradle abc,我如何将它插入到 gradle 的生命周期中,这必须影响 android studio 正在构建的 apk 并基于修改后的类文件启动 apk
      • 我认为这非常违背 gradle 构建系统的意图。是的,它有效,但问题是你是否真的想这样做。将dependsOn 设为无序的决定是discussed at length in the gradle jira and forums,它是故意无序的。
      • 你的意思是我的回答还是他的附加问题?我会同意这两者,但似乎他不想根据我们给他的提示(dependsOn 带字符串,任务排序mustRunAfter / shouldRunAfter)自行搜索合适的解决方案。
      • 好的,我看到了额外的 cmets,我同意。如果你真的不能使用 gradle 为你提供的工具来解决这个问题,那么这至少是一个可行的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多