I want to do some long running task on a button click, if user click again on that button current task forcefully stopped and will do next task ?
I am posting a pure Java based code which will work in android as well. While working with android Just you need to take care that you do not update GUI from a part of the program which gets executed in a Thread other than Main GUI thread. If You wish to edit the GUI from another thread then you may use Handler instantiated in the main GUI thread.
Define the basic interface for such model
/**
*
* @author nits.kk
*
* This defines the methods for the model.
*
*/
public interface IResumable {
/**
* starts the model
*/
public void requestStart();
/**
* requests the model to pause
*/
public void requestPause();
/**
* requests the model to resume with new parameter
* @param newParam
*/
public void resumeWithNewParam(int newParam);
/**
* terminate the model
*/
public void requestStop();
}
Now the concrete implementation
public class ResumableModel implements IResumable {
private Thread worker;
private WorkerRunnable work;
public ResumableModel(int initialValue) {
work = new WorkerRunnable(initialValue);
worker = new Thread(work);
}
@Override
public void requestStart() {
worker.start();
}
@Override
public void requestPause() {
work.setPauseRequested(true);
}
@Override
public void resumeWithNewParam(int newParam) {
work.setNewParam(newParam);
}
@Override
public void requestStop() {
worker.interrupt();
}
private static class WorkerRunnable implements Runnable {
private int param; // we can have the variable of the type depending upon the requirement.
private final Object lock = new Object();
private volatile boolean isPauseRequested = false;
public void run() {
synchronized (lock) {
try {
while (!Thread.currentThread().isInterrupted()) {
while (isPauseRequested) {
lock.wait();
}
System.out.println("value of param is" + param);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public WorkerRunnable(int param) {
this.param = param;
}
private void setPauseRequested(boolean isPauseRequested) {
this.isPauseRequested = isPauseRequested;
}
private void setNewParam(int param) {
// double locking to prevent the calling thread from being locked
// (if in running state without pause requested then calling thread
// will be in indefinite wait state for acquiring the lock.
if (isPauseRequested) {
synchronized (lock) {
if (isPauseRequested) {
this.param = param;
this.isPauseRequested = false;
lock.notifyAll();
} else {
// logger will be used in real application
System.out.println("Need to pause first before setting a new param");
}
}
} else {
// logger will be used in real application
System.out.println("Need to pause first before setting a new param");
}
}
}
}
Now when you wish to start The thread you can do as below
IResumable resumable = new ResumableModel(10);
resumable.requestStart();
When you want to pause the thread you can simply invoke the requestPause() method
resumable.requestPause();
Now when you need to resume the Thread with a new variable value, you can invoke resumeWithNewParam.
resumable.resumeWithNewParam(20);
Now when you feel you do not need the thread and model should terminate then you can invoke resumable.requestStop();