How to force an IntentService to stop immediately with a cancel button from an Activity? How to force an IntentService to stop immediately with a cancel button from an Activity? android android

How to force an IntentService to stop immediately with a cancel button from an Activity?


Here is the trick, make use of a volatile static variable and check continue condition in some of lines in your service that service continue should be checked:

class MyService extends IntentService {    public static volatile boolean shouldContinue = true;    public MyService() {        super("My Service");    }    @Override    protected void onHandleIntent(Intent intent) {        doStuff();    }    private void doStuff() {        // do something         // check the condition        if (shouldContinue == false) {            stopSelf();            return;        }       // continue doing something       // check the condition       if (shouldContinue == false) {           stopSelf();           return;       }       // put those checks wherever you need   }}

and in your activity do this to stop your service,

 MyService.shouldContinue = false;


Stopping a thread or a process immediately is often a dirty thing. However, it should be fine if your service is stateless.

Declare the service as a separate process in the manifest:

<service     android:process=":service"     ...

And when you want to stop its execution, just kill that process:

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();Iterator<RunningAppProcessInfo> iter = runningAppProcesses.iterator();while(iter.hasNext()){    RunningAppProcessInfo next = iter.next();    String pricessName = getPackageName() + ":service";    if(next.processName.equals(pricessName)){        Process.killProcess(next.pid);        break;    }}


I've used a BroadcastReceiver inside the service that simply puts a stop boolean to true. Example:

private boolean stop=false;public class StopReceiver extends BroadcastReceiver {   public static final String ACTION_STOP = "stop";   @Override   public void onReceive(Context context, Intent intent) {       stop = true;   }}@Overrideprotected void onHandleIntent(Intent intent) {    IntentFilter filter = new IntentFilter(StopReceiver.ACTION_STOP);    filter.addCategory(Intent.CATEGORY_DEFAULT);    StopReceiver receiver = new StopReceiver();    registerReceiver(receiver, filter);    // Do stuff ....    //In the work you are doing    if(stop==true){        unregisterReceiver(receiver);        stopSelf();    }}

Then, from the activity call:

//STOP SERVICEIntent sIntent = new Intent();sIntent.setAction(StopReceiver.ACTION_STOP);sendBroadcast(sIntent);

To stop the service.

PD: I use a boolean because In my case I stop the service while in a loop but you can probably call unregisterReceiver and stopSelf in onReceive.

PD2: Don't forget to call unregisterReceiver if the service finishes it's work normally or you'll get a leaked IntentReceiver error.