2

I have a background service in my android application.In which a thread listening recent tasks running frequently.My service overrides both onCreate() and onStartCommand() methods. When i tried to open some applications like Gallery,Camera etc..., the service will be stopped.It calls the onCreate() method only and not onDestroy() or onStartCommand().I tried to override onLowMemory() in this service but it logs nothing.The application saved internally by specifying

 android:installLocation="internalOnly"  

in the manifest file.

Note: This issue noticed on Micromax A54 2.3.5.

Why does the background service stops sometimes? Is there any solution for this issue?

public class MyService extends Service {

    public MyService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {
            if(intent != null){
                //......
            }
        } catch (Throwable e) {
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //......
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


}

And start the service like this

Intent intent = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(intent);
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Devu Soman
  • 2,246
  • 13
  • 36
  • 57
  • Your service is killed by the OS. – Hoan Nguyen May 13 '13 at 04:11
  • How can i solve this issue? – Devu Soman May 13 '13 at 04:22
  • Save want you need in SharedPreferences and check the for it in onStartCommand. Clear the prefs in onDestroy – Hoan Nguyen May 13 '13 at 04:25
  • Hard to believe. If Android kills the process hosting your `Service` (and you returned `START_STICKY` from `onStartCommand()` then Android will create a new process for your `Service` and start it again, calling `onCreate()` and `onStartCommand()`. That's how it works. There are some devices that require that apps that want to have background services running all the time be authorized. The user must do this by going to a settings screen and authorizing the specific app to run in the background. This is known as "protected apps" on some devices and by other names as well. Once your app is – David Wasser Jan 17 '17 at 11:22
  • added to the list of "protected apps", it will be properly restarted by Android if the process is killed. – David Wasser Jan 17 '17 at 11:23

4 Answers4

2

Android can stop any service at any time for any reason. A typical reason is low memory (killing the service to give its memory elsewhere), but I've seen at least a few devices that kill them every X hours regardless. There is no way to ensure you always run. The best you can do is have all your activities try to start your service (in case it isn't running), write your service so it can reload needed data, and set yourself as START_STICKY so if it has enough memory the framework will restart you later.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • 1
    My service called its onCreate() after stopping ,but the functionalities are specified in onStartCommand().How can i solve this problem? – Devu Soman May 13 '13 at 04:21
  • Hacve the service's onCreate call startService on its own class. That way the service restarts itself. – Gabe Sechan May 13 '13 at 04:22
  • This makes no sense. If Android recreates the `Service` and calls `onCreate()`, then it will also call `onStartCommand()`. There is no reason to call `startService()` in `onCreate()`. – David Wasser Jan 17 '17 at 11:19
  • @DavidWasser This is a 4 year old answer. Back then, it didn't – Gabe Sechan Jan 17 '17 at 12:54
  • Hard to believe. Sounds to me like OP has a different problem. But, hey, OP accepted your answer, so it must have worked for him/her! – David Wasser Jan 17 '17 at 13:35
  • @DavidWasser I had the same problem. It was necessary back in the 2.2 days – Gabe Sechan Jan 17 '17 at 13:35
1

Android stops service when memory needs. You can use

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    try {
        if(intent != null){
            //......
        }
    } catch (Throwable e) {
    }
    return START_REDELIVER_INTENT;
}

START_REDELIVER_INTENT can be used.if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then it will be scheduled for a restart and the last delivered Intent re-delivered to it again via onStartCommand(Intent, int, int).

Bhavesh Hirpara
  • 22,255
  • 15
  • 63
  • 104
  • I am not sure but the document seems to say that the START_REDELIVER_INTENT is for IntentService. – Hoan Nguyen May 13 '13 at 04:30
  • I don't think so.. I have used before and it's working fine for me. – Bhavesh Hirpara May 13 '13 at 04:34
  • OK, the document is not very clear when it talks about pending intent, so I never used them before. – Hoan Nguyen May 13 '13 at 04:36
  • OP is returning `START_STICKY` from `onStartCommand()`, which indicates that he wants his `Service` to be restarted if it is killed by the Android framework.Changing the return value to `START_REDELIVER_INTENT` isn't going to improve that behaviour. – David Wasser Jan 17 '17 at 11:26
0

I met the same issue. On some devices after a while Android kills my service and even startForeground() does not help. And my customer does not like this issue.

I use SharedPreferences to keep the flag whether the service should be running. Also I use AlarmManager to create a kind of watchdog timer. It checks from time to time if the service should be running and restart it.

Creating/dismissing my watchdog timer:

void setServiceWatchdogTimer(boolean set, int timeout)
{
    Intent intent;
    PendingIntent alarmIntent;
    intent = new Intent(); // forms and creates appropriate Intent and pass it to AlarmManager
    intent.setAction(ACTION_WATCHDOG_OF_SERVICE);
    intent.setClass(this, WatchDogServiceReceiver.class);
    alarmIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
    if(set)
        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, alarmIntent);
    else
        am.cancel(alarmIntent);
}

Receiving and processing the intent from the watchdog timer:

/** this class processes the intent and
 *  checks whether the service should be running
 */
public static class WatchDogServiceReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {

        if(intent.getAction().equals(ACTION_WATCHDOG_OF_SERVICE))
        {
            // check your flag and 
            // restart your service if it's necessary
        }
    }
}

Indeed I use WakefulBroadcastReceiver instead of BroadcastReceiver. I gave you the code with BroadcastReceiver just to simplify it.

ivan
  • 359
  • 3
  • 11
0

You have this code in your Service.onStartCommand():

if(intent != null){

You do realize that if Android kills the process hosting your Service, it will create a new process and create a new instance of your Service and restart it, calling onCreate() and then calling onStartCommand() with a null Intent. This is probably what is happening and why you think that onStartCommand() is not being called.

David Wasser
  • 93,459
  • 16
  • 209
  • 274