stopSelf() vs stopSelf(int) vs stopService(Intent)

What's the difference in calling
stopSelf() , stopSelf(int) or stopService(new Intent(this,MyServiceClass.class))
inside onStartCommand() ?

for example if I start the same services twice this way:

...
Intent myIntent1 = new Intent(AndroidAlarmService.this, MyAlarmService.class);
myIntent1.putExtra("test", 1); 
Intent myIntent2 = new Intent(AndroidAlarmService.this, MyAlarmService.class);
myIntent2.putExtra("test", 2);
startService(myIntent1);
startService(myIntent2);
...

And implement onStartCommand in this way:

public int onStartCommand(Intent intent, int flags, int startId)
{
Toast.makeText(this, "onStartCommand called "+intent.getIntExtra("test", 0), Toast.LENGTH_LONG).show();
stopService(new Intent(this,MyAlarmService.class));
return START_NOT_STICKY;
}

I get exactly the same behaviour with the three methods, that is onDestroy will only be called after onStartCommand is executed twice.


Solution 1:

I hope this will help you:

A started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand() returns. So, the service must stop itself by calling stopSelf() or another component can stop it by calling stopService().

Once requested to stop with stopSelf() or stopService(), the system destroys the service as soon as possible.

However, if your service handles multiple requests to onStartCommand() concurrently, then you shouldn't stop the service when you're done processing a start request, because you might have since received a new start request (stopping at the end of the first request would terminate the second one). To avoid this problem, you can use stopSelf(int) to ensure that your request to stop the service is always based on the most recent start request.

That is, when you call stopSelf(int), you pass the ID of the start request (the startId delivered to onStartCommand()) to which your stop request corresponds. Then if the service received a new start request before you were able to call stopSelf(int), then the ID will not match and the service will not stop.

Solution 2:

Here's a simplified description:

  • stopSelf() is used to always stop the current service.

  • stopSelf(int startId) is also used to stop the current service, but only if startId was the ID specified the last time the service was started.

  • stopService(Intent service) is used to stop services, but from outside the service to be stopped.

This is the reference page.

Solution 3:

The core functionality of all 3 methods are same and that's why they are having similar names. There are very small differences among them.

  • public final void stopSelf()

Class : This belongs to android.app.Service class

Called From : This method is intended to get called from inside the service only.

Behavior : Service will get stopped. onDestroy() state called.

  • public final void stopSelf(int startId)

Class : This belongs to android.app.Service class

Called From : This method is intended to get called from inside the service only.

Behavior : There is a method from older version stopSelfResult(int startId). This method is newer version of that method. Service will get stopped only if the most recent time it was started was startId. onDestroy() state called.

May be you can find this method helpful only in a case where you started 2-3 instance of same service but you want to stop them in a order you received with startId list stored with you. Need to be very careful while using this method.

  • public abstract boolean stopService(Intent service)

Class : This belongs to android.content.Context class

Called From : This method is intended to get called from outside the service though you are allowed to call from inside.

Behavior : If the service is not running, nothing happens. Otherwise it is stopped. Note that calls to startService() are not counted -- this stops the service no matter how many times it was started. onDestroy() state called.