Android development
IntentService
Service lifecycle
START_STICKY
START_NOT_STICKY

START_STICKY and START_NOT_STICKY

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

START_STICKY and START_NOT_STICKY are return values from Service.onStartCommand that tell Android what to do if the system kills your started service after onStartCommand has returned. They do not control whether the service is killed, but they do influence whether the system tries to recreate it later.

What START_STICKY Means

If you return START_STICKY, Android may recreate the service after it has enough resources again. When that restart happens, onStartCommand may be called with a null intent if there is no specific start request to redeliver.

java
1import android.app.Service;
2import android.content.Intent;
3import android.os.IBinder;
4
5public class PlayerService extends Service {
6
7    @Override
8    public int onStartCommand(Intent intent, int flags, int startId) {
9        // Start or continue ongoing playback logic here.
10        return START_STICKY;
11    }
12
13    @Override
14    public IBinder onBind(Intent intent) {
15        return null;
16    }
17}

This behavior is appropriate for services that represent an ongoing background role, such as media playback or another process that should keep existing even if the specific start intent is gone.

What START_NOT_STICKY Means

If you return START_NOT_STICKY, Android does not recreate the service automatically after killing it. The service stays stopped until something explicitly starts it again.

java
1import android.app.Service;
2import android.content.Intent;
3import android.os.IBinder;
4
5public class CleanupService extends Service {
6
7    @Override
8    public int onStartCommand(Intent intent, int flags, int startId) {
9        new Thread(() -> {
10            performCleanup();
11            stopSelf();
12        }).start();
13        return START_NOT_STICKY;
14    }
15
16    private void performCleanup() {
17        // Cleanup task here.
18    }
19
20    @Override
21    public IBinder onBind(Intent intent) {
22        return null;
23    }
24}

This is a better fit for one-off background work where restarting automatically would be wasteful or misleading.

Choose Based on Service Intent

A practical rule is:

  • Use START_STICKY when the service represents ongoing behavior that should resume.
  • Use START_NOT_STICKY when the service is just doing a task and can safely disappear if killed.

There is also START_REDELIVER_INTENT, which tells Android to restart the service and redeliver the last intent. That is often useful when the input request itself matters for finishing the task.

Modern Android Context

These constants still matter, but they are not a complete background-work strategy. Modern Android places strict limits on background execution. If the work must continue visibly for the user, a foreground service is often the right model. If the work is deferrable or guaranteed background work, WorkManager is usually a better fit than a plain started service.

That means the choice is not only STICKY versus NOT_STICKY. It is also whether a started service is the right primitive at all.

Common Pitfalls

The biggest mistake is thinking START_STICKY guarantees the service will never stop. It does not. It only influences restart behavior after the system kills the service. The system can still kill it under pressure.

Another issue is forgetting that a restarted sticky service may receive a null intent. If your logic assumes every restart has full intent extras, the service can crash or behave incorrectly.

Developers also sometimes use started services for background jobs that should really be scheduled work. On modern Android, forcing everything through long-lived services can lead to lifecycle problems and policy issues.

Finally, START_NOT_STICKY does not mean "run once successfully." If the service is killed before completing its work, Android simply will not restart it for you. If completion matters, consider START_REDELIVER_INTENT, a foreground service, or WorkManager.

Summary

  • 'START_STICKY asks Android to recreate the service later if it gets killed.'
  • 'START_NOT_STICKY tells Android not to restart the service automatically.'
  • Sticky restarts may come back with a null intent.
  • Choose the return value based on whether the service represents ongoing behavior or one-off work.
  • For many modern background tasks, WorkManager or a foreground service is a better design than a plain started service.

Course illustration
Course illustration

All Rights Reserved.