資料流動作支援是一個孵化中的功能,可能會有所變更。 |
在 Gradle 建置中執行工作的首選方式是使用工作 (task)。然而,某些種類的工作不太適合使用工作,例如自訂處理建置失敗。
如果您想要在建置成功時播放歡快的聲音,在建置失敗時播放悲傷的聲音呢?這個工作片段必須處理工作執行結果,因此它本身不能是一個工作。
Dataflow Actions API 提供了一種排程此類型工作的方式。資料流動作是一個參數化的隔離工作片段,一旦所有輸入參數都可用,它就會符合執行資格。
實作資料流動作
第一步是實作動作本身。您必須建立一個類別來實作 FlowAction 介面
import org.gradle.api.flow.FlowAction
import org.gradle.api.flow.FlowParameters
abstract class ReportConsumption : FlowAction<ReportConsumption.Params> {
interface Params : FlowParameters {
}
override fun execute(parameters: Params) {
}
}
必須實作 execute
方法,因為這是工作發生的位置。動作實作被視為自訂 Gradle 類型,並且可以使用自訂 Gradle 類型可用的任何功能。特別是,某些 Gradle 服務可以注入到實作中。
資料流動作可以接受參數。要提供參數,您可以定義一個抽象類別 (或介面) 來保存參數
-
參數類型必須實作 (或擴展) FlowParameters。
-
參數類型也是自訂 Gradle 類型。
-
動作實作會將參數作為
execute
方法的引數取得。
當動作不需要參數時,您可以使用 FlowParameters.None 作為參數類型。
這裡有一個資料流動作的範例,它接受共用建置服務和檔案路徑作為參數
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 還為建置生命週期事件 (例如建置完成) 提供了專用的提供者。這些提供者適用於資料流動作,並在用作輸入時提供額外的排序保證。如果您透過例如呼叫 map
或 flatMap
從事件提供者衍生提供者,則排序也適用。您可以從 FlowProviders 類別取得這些提供者。
flowProviders.buildWorkResult.map {
[
buildInvocationId: scopeIdsService.buildInvocationId,
workspaceId: scopeIdsService.workspaceId,
userId: scopeIdsService.userId
]
}
如果您沒有使用生命週期事件提供者作為資料流動作的輸入,則動作執行的確切時間未定義,並且可能會在下一個 Gradle 版本中變更。 |
提供動作以供執行
您不應手動建立 FlowAction
物件。相反地,您應該在 FlowScope
的適當範圍內請求執行它們。這樣做時,您可以配置任務的參數
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 | 使用服務注入來取得 FlowScope 和 FlowProviders 實例。它們適用於專案和設定外掛程式。 |
2 | 使用適當的範圍來執行您的動作。顧名思義,always 範圍中的動作會在每次建置執行時執行。 |
3 | 指定實作動作的類別。 |
4 | 使用 spec 引數來配置動作參數。 |
5 | 生命週期事件提供者可以對應到其他事物,同時保留動作順序。 |
因此,當您執行建置且建置成功完成時,動作將播放 "tada" 聲音。如果建置在配置或執行時失敗,您會聽到 "sad-trombone" 聲音 — 假設建置配置進行得夠遠,足以註冊動作。