資料流程動作支援是 孵化 功能,且這裡描述的詳細資料可能會變更。

在 Gradle 建置中執行工作的優先方式是使用任務。但是,有些類型的任務並不適合任務,例如自訂處理建置失敗。如果您希望在建置成功時播放歡樂的聲音,而在建置失敗時播放悲傷的聲音,該怎麼辦?這項工作必須處理任務執行結果,因此它本身不能是任務。

資料流程動作 API 提供一種排程此類工作的方式。資料流程動作是參數化的孤立工作,只要其所有輸入參數都可用,就會符合執行資格。

實作資料流程動作

第一步是實作動作本身。為此,請建立實作 FlowAction 介面的類別。必須實作 execute 方法,因為這是工作發生的地方。動作實作被視為 自訂 Gradle 類型,且可以使用自訂 Gradle 類型可用的任何功能。特別是,可以將一些 Gradle 服務注入到實作中。

資料流程動作可以接受參數。若要提供參數,請定義一個抽象類別 (或介面) 來存放參數。參數類型必須實作 (或延伸) FlowParameters。動作實作會取得參數作為 execute 方法的引數。參數類型也是 自訂 Gradle 類型

當動作不需要參數時,可以使用 FlowParameters.None 作為參數類型。

以下是資料流程動作的範例,它採用共用建置服務和檔案路徑作為參數。

SoundPlay.java
package org.gradle.sample.sound;

import org.gradle.api.flow.FlowAction;
import org.gradle.api.flow.FlowParameters;
import org.gradle.api.provider.Property;
import org.gradle.api.services.ServiceReference;
import org.gradle.api.tasks.Input;

import java.io.File;

public abstract class SoundPlay implements FlowAction<SoundPlay.Parameters> {
    interface Parameters extends FlowParameters {
        @ServiceReference (1)
        Property<SoundService> getSoundService();

        @Input (2)
        Property<File> getMediaFile();
    }

    @Override
    public void execute(Parameters parameters) {
        parameters.getSoundService().get().playSoundFile(parameters.getMediaFile().get());
    }
}
1 參數類型中的參數必須加上註解。如果參數加上 @ServiceReference 註解,則會在建立動作時根據 一般規則 自動將適當的共用建置服務實作指定給參數。
2 所有其他參數都必須加上 @Input 註解。

生命週期事件提供者

除了常見的值提供者之外,Gradle 也提供專門針對建置生命週期事件(例如建置完成)的提供者。這些提供者是針對資料流程動作設計,並在用作輸入時提供額外的排序保證。如果您透過呼叫 mapflatMap 等方式從事件提供者衍生提供者,排序也會套用。您可以從 FlowProviders 類別取得這些提供者。

如果您沒有將生命週期事件提供者用作資料流程動作的輸入,則動作執行的確切時間未定義,且可能會在 Gradle 的下一個版本中變更。

提供要執行的動作

您不應該手動建立 FlowAction 物件。相反地,您要求在 FlowScope 的適當範圍中執行它們。這樣做時,您可以設定工作要使用的參數。

SoundFeedbackPlugin.java
package org.gradle.sample.sound;

import org.gradle.api.Plugin;
import org.gradle.api.flow.FlowProviders;
import org.gradle.api.flow.FlowScope;
import org.gradle.api.initialization.Settings;

import javax.inject.Inject;
import java.io.File;

public abstract class SoundFeedbackPlugin implements Plugin<Settings> {
    @Inject
    protected abstract FlowScope getFlowScope(); (1)

    @Inject
    protected abstract FlowProviders getFlowProviders(); (1)

    @Override
    public void apply(Settings settings) {
        final File soundsDir = new File(settings.getSettingsDir(), "sounds");
        getFlowScope().always( (2)
            SoundPlay.class,  (3)
            spec ->  (4)
                spec.getParameters().getMediaFile().set(
                    getFlowProviders().getBuildWorkResult().map(result -> (5)
                        new File(
                            soundsDir,
                            result.getFailure().isPresent() ? "sad-trombone.mp3" : "tada.mp3"
                        )
                    )
                )
        );
    }
}
1 使用服務注入取得 FlowScopeFlowProviders 執行個體。它們可供專案和設定外掛使用。
2 使用適當的範圍來執行您的動作。顧名思義,always 範圍中的動作會在每次執行建置時執行。
3 指定實作動作的類別。
4 使用 spec 參數設定動作參數。
5 生命週期事件提供者可以對應到其他項目,同時保留動作排序。

因此,當您執行建置且建置順利完成時,動作會播放「tada」音效。如果建置在設定或執行時間失敗,您會聽到「sad-trombone」音效,當然前提是建置設定已進行到足以註冊動作的程度。