I use a bound service to run cpu-intensive tasks in the background as recommended to avoid ANR. The client application sends messages to the bound service that handles them in the handleMessage()
method of its Handler
.
As some requests can take very long to answer, I want to offer the user the ability to "abort/abandon" a running request. However, I can not destroy the service because I need to keep its context for future requests. Sending an "abort" request from the application will be queued and handled by the service after it will have completed its current task, which is obviously too late and not implementing the requested functionality.
Is there a way for the client application to kill a running request without killing the service and losing its associated context?
* EDIT * Thanks to Mario's recommendation and this link, here is the solution I have implemented:
ExecutorService executor = Executors.newFixedThreadPool(1);
private volatile static Future<?> BackgroundSolveFuture = null;
public class IncomingHandler extends Handler {
@Override
public void handleMessage(Message message) {
msg = message;
msgArg1 = message.arg1;
msgWhat = message.what;
if (message.replyTo != null) {
mClient = new Messenger(message.replyTo.getBinder());
}
switch (msgWhat) {
case MSG_ABORT:
BackgroundSolveFuture = null;
break;
case MSG_SOLVE:case MSG_ANALYZE:case MSG_SUGGEST:case MSG_STEP:
BackgroundSolveFuture = executor.submit(new Runnable() {
public void run() {
solve();
}
});
break;
...
Inside solve()
I regularly check whether BackgroundSolveFuture
has been set to null
:
if (BackgroundSolveFuture == null) {
undoAction(true);
return;
}