このために、java.util.concurrentにある機能を使用できます。
UI を含む既存のクラスに、次のようなものを追加する必要があります。
//class variable to store the future of your task
private Future<?> taskFuture = null;
//to be called from button "Start" action handler
public void actionStart() {
//don't double start, if there is one already running
if(taskFuture == null || taskFuture.isDone()) {
//create the new runnable instance, with the proper commands to execute
MyShellExecutor ex = new MyShellExecutor(new String[] { "sh",testPath + "/install.sh", cmd, "&" });
//we only need one additional Thread now, but this part can be tailored to fit different needs
ExecutorService newThreadExecutor = Executors.newSingleThreadExecutor();
//start the execution of the task, which will start execution of the shell command
taskFuture = newThreadExecutor.submit(ex);
}
}
//to be called from button "Stop" action handler
public void actionStop() {
//if not already done, or cancelled, cancel it
if(taskFuture !=null && !taskFuture.isDone()) {
taskFuture.cancel(true);
}
}
ジョブを実行する主要なコンポーネントは、Runnable
私が名前を付けたMyShellExecutor
で、次のようになります。
public class MyShellExecutor implements Runnable {
//stores the command to be executed
private final String[] toExecute;
public MyShellExecutor(String[] toExecute) {
this.toExecute=toExecute;
}
public void run() {
Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(toExecute);
int exitValue = process.waitFor();
System.out.println("exit value: " + exitValue);
BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = buf.readLine()) != null) {
System.out.println("exec response: " + line);
//do whatever you need to do
}
} catch (InterruptedException e) {
//thread was interrupted.
if(process!=null) { process.destroy(); }
//reset interrupted flag
Thread.currentThread().interrupt();
} catch (Exception e) {
//an other error occurred
if(process!=null) { process.destroy(); }
}
}
}
注: 時間のかかる操作を実行する場合は、UI スレッドで実行しないようにしてください。それはユーザーをブロックするだけで、優れたユーザー エクスペリエンスを提供しません。ユーザーを別のスレッドで待たせる可能性のあることを常に実行します。
推奨読書: Java Concurrency In Practice