Background Service getting killed in android
IntentService
is not intended to keep running in a while
loop. The idea is to react to an Intent
, do some processing and stop the service once done.
That does not mean that it's not working and I can't tell you why you see such long delays but the cleaner solution is to use some external source to poke the service periodically. Besides vanilla Java methods you can also have a look at the AlarmManager
or a Handler
as mentioned in the AlarmManager
documentation.
The Handler
way would work like this
public class TriggerActivity extends Activity implements Handler.Callback {
// repeat task every 60 seconds
private static final long REPEAT_TIME = 60 * 1000;
// define a message id
private static final int MSG_REPEAT = 42;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler(this);
}
@Override
protected void onStart() {
super.onStart();
// start cycle immediately
mHandler.sendEmptyMessage(MSG_REPEAT);
}
@Override
protected void onStop() {
super.onStop();
// stop cycle
mHandler.removeMessages(MSG_REPEAT);
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler = null;
}
@Override
public boolean handleMessage(Message msg) {
// enqueue next cycle
mHandler.sendEmptyMessageDelayed(MSG_REPEAT, REPEAT_TIME);
// then trigger something
triggerAction();
return true;
}
private void triggerAction() {
// trigger the service
Intent serviceIntent = new Intent(this, MyService.class);
serviceIntent.setAction("com.test.intent.OPTIONAL_ACTION");
startService(serviceIntent);
}
}
A simple Activity
(which could be extended to have that functionality in all your activities) that sends itself a Message
all the time while it is running (here between onStart
and onStop
)
The main problem is that we cannot say
Services are not meant to be killed. They are meant to run in background as long as we want it to.
Basically, that is not true. System still can terminate the service in low memory and possibly other situations. There are 2 ways to overcome this:
- If you are implementing the service, override
onStartCommand()
and returnSTART_STICKY
as the result. It will tell the system that even if it will want to kill your service due to low memory, it should re-create it as soon as memory will be back to normal. - If you are not sure 1st approach will work - you'll have to use AlarmManager http://developer.android.com/reference/android/app/AlarmManager.html . That is a system service, which will execute actions when you'll tell, for example periodically. That will ensure that if your service will be terminated, or even the whole process will die(for example with force close) - it will be 100% restarted by AlarmManager.
Good luck
You could use ScheduledExecutorService designed specifically for such purpose.
Don't use Timers, as demonstrated in "Java Concurrency in Practice" they can be very inaccurate.