Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can we prevent a Service from being killed by OS?

I am using Service in my application and it needs to run until my application is uninstalled, but the problem is it gets killed by OS.

How can we prevent it from being killed by OS? Or if it gets killed can we restart that service again through programmatically?

like image 627
Rahul Avatar asked Mar 14 '12 06:03

Rahul


4 Answers

You may run the service in the foreground using startForeground().

A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory.

But bear in mind that a foreground service must provide a notification for the status bar (read here), and that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.

Note: This still does not absolutely guarantee that the service won't be killed under extremely low memory conditions. It only makes it less likely to be killed.

like image 191
Dheeraj Vepakomma Avatar answered Nov 10 '22 03:11

Dheeraj Vepakomma


I've been puzzled by the same issue to yours recently.but now,I've found a good solution. First of all,you should know that, even your service was killed by OS, the onCreate method of your service would be invoked by OS in a short while.So you can do someting with the onCreate method like this:

@Override
public void onCreate() {
    Log.d(LOGTAG, "NotificationService.onCreate()...");
    //start this service from another class
    ServiceManager.startService();
}
@Override
public void onStart(Intent intent, int startId) {
    Log.d(LOGTAG, "onStart()...");
    //some code of your service starting,such as establish a connection,create a TimerTask or something else
}

the content of "ServiceManager.startService()" is:

public static void startService() {
    Log.i(LOGTAG, "ServiceManager.startSerivce()...");
    Intent intent = new Intent(NotificationService.class.getName());
    context.startService(intent);
}

However, this solution is just available for the situation of your service being killed by GC.Sometimes our service might be killed by user with Programme Manager.In this situation,your prosses will be killed,and your service will never been re-instantiated.So your service can not be restarted. But the good news is,when the PM kill your service,it will call your onDestroy method.So we can do something with that method.

    @Override
public void onDestroy() {
    Intent in = new Intent();
    in.setAction("YouWillNeverKillMe");
    sendBroadcast(in);
    Log.d(LOGTAG, "onDestroy()...");
}

The string of "YouWillNeverKillMe" is a custom action. The most important thing of this method is,don't add any code before send the broadcast.As system will not wait for completion of onDestroy(),you must send out the broadcast as soon as posible. Then regist a receiver in manifast.xml:

<receiver android:name=".app.ServiceDestroyReceiver" >
        <intent-filter>
            <action android:name="YouWillNeverKillMe" >
            </action>
        </intent-filter>
    </receiver>

Finally,create a BroadcastReceiver,and start your service in the onReceive method:

@Override
public void onReceive(Context context, Intent intent) {
    Log.d(LOGTAG, "ServeiceDestroy onReceive...");
    Log.d(LOGTAG, "action:" + intent.getAction());
    Log.d(LOGTAG, "ServeiceDestroy auto start service...");
    ServiceManager.startService();
}

Hope this will be helpful to you,and excuse my poor written english.

like image 34
Alaowan Avatar answered Nov 10 '22 02:11

Alaowan


Override method onStartCommand() in your service class and simply return START_STICKY (as suggested by "Its not blank"). That's all you need. If the process that runs your service gets killed (by a low memory condition for example), the Android system will restart it automatically (usually with some delay, like 5 seconds).

Don't use onStart() anymore as suggested in another answer, it's deprecated.

like image 10
Chris Avatar answered Nov 10 '22 02:11

Chris


use

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    //**Your code **
    // We want this service to continue running until it is explicitly
    // stopped, so return sticky.
    return START_STICKY;
} 

ref Documentation lifecycle of Service.

Edit added method.

like image 9
Its not blank Avatar answered Nov 10 '22 02:11

Its not blank