如何判断Gradle进程已结束?并行任务完成后触发后续操作
Great question! Handling parallel Gradle tasks and waiting for all to finish before running a post-operation depends a bit on your OS, but we’ve got solid options for both shell scripts (the simplest approach for most cases) and Java code (if you need programmatic control). Let’s break this down:
This is usually the easiest way since it leverages native OS process management tools.
Windows (Batch Script)
Your original start commands launch tasks in new windows, but they don’t track when the tasks finish. Instead, we’ll launch tasks in the background, capture their process IDs (PIDs), and wait for each PID to exit before running your post-operation:
@echo off setlocal enabledelayedexpansion :: Start Gradle tasks in background and capture their PIDs start /B gradlew.bat runSuite1 -i --rerun-tasks set "PID1=!ERRORLEVEL!" start /B gradlew.bat runSuite2 -i --rerun-tasks set "PID2=!ERRORLEVEL!" :: Wait for the first task to finish :WAIT_FOR_PID1 tasklist /FI "PID eq !PID1!" | find /I "java.exe" >nul if not errorlevel 1 ( timeout /t 1 /nobreak >nul goto WAIT_FOR_PID1 ) :: Wait for the second task to finish :WAIT_FOR_PID2 tasklist /FI "PID eq !PID2!" | find /I "java.exe" >nul if not errorlevel 1 ( timeout /t 1 /nobreak >nul goto WAIT_FOR_PID2 ) :: Run your post-operation here echo All Gradle tasks completed! Executing post-operation... :: Add your post-operation command (e.g., copy files, send notification)
macOS/Linux (Bash Script)
On Unix-like systems, the & operator backgrounds processes, and we can use the built-in wait command to block until all specified PIDs exit:
#!/bin/bash # Start both Gradle tasks in the background and capture their PIDs ./gradlew runSuite1 -i --rerun-tasks & PID1=$! ./gradlew runSuite2 -i --rerun-tasks & PID2=$! # Wait for both processes to finish wait $PID1 $PID2 # Run your post-operation here echo "All Gradle tasks completed! Executing post-operation..." # Add your post-operation command (e.g., ./cleanup.sh, curl https://your-webhook.com)
If you need to integrate this logic into a Java application or want more control over process output/error handling, use ProcessBuilder to launch and track each Gradle process:
import java.io.IOException; public class GradleTaskCoordinator { public static void main(String[] args) throws IOException, InterruptedException { // Determine the correct Gradle executable based on OS String gradleExec = System.getProperty("os.name").toLowerCase().contains("win") ? "gradlew.bat" : "./gradlew"; // Define process builders for each suite ProcessBuilder suite1Builder = new ProcessBuilder(gradleExec, "runSuite1", "-i", "--rerun-tasks"); ProcessBuilder suite2Builder = new ProcessBuilder(gradleExec, "runSuite2", "-i", "--rerun-tasks"); // Start both processes Process suite1Process = suite1Builder.start(); Process suite2Process = suite2Builder.start(); // Wait for both processes to complete (this blocks until each finishes) int exitCode1 = suite1Process.waitFor(); int exitCode2 = suite2Process.waitFor(); // Optional: Check if tasks succeeded if (exitCode1 == 0 && exitCode2 == 0) { System.out.println("All Gradle tasks completed successfully!"); } else { System.out.printf("One or more tasks failed. Exit codes: Suite1=%d, Suite2=%d%n", exitCode1, exitCode2); } // Execute your post-operation here System.out.println("Running post-operation..."); // Example: Launch a cleanup process Process postOpProcess = new ProcessBuilder("echo", "Post-operation completed!").start(); postOpProcess.waitFor(); } }
Key Notes for Java Implementation:
- OS Compatibility: The code checks the OS to use
gradlew.bat(Windows) or./gradlew(macOS/Linux). - Output Handling: If you need to capture Gradle’s logs, read from
process.getInputStream()andprocess.getErrorStream()(use separate threads to avoid blocking the main thread). - Scalability: For more than two tasks, store
ProcessBuilderinstances in a list, loop to start them, then loop to callwaitFor()on each process.
内容的提问来源于stack exchange,提问作者PrakashFrancis

