I want to keep a IntentService
running in background even when the app is killed. And by "killed" I mean press home-button for a long time -> see all running apps -> swipe my app aside -> app killed OR press back-button for a long time -> app killed
My code goes as follows. In my MainActivity:
Intent intent = new Intent(this, MyService.class);
this.startService(intent);
In my MyService:
public class MyService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
System.out.println("MyService started");
run();
}
private void run() {
while (true){
System.out.println("MyService still running");
doSomething();
waitSomeTime();
}
}
}
I see that the service is running when the app is open. It's still running when I minimize the app via home-button. It's still running when I close the app via back-button. But it will stop if I kill it as mentioned above. How do I solve this?
If your Service is started by your app then actually your service is running on main process. so when app is killed service will also be stopped. So what you can do is, send broadcast from
onTaskRemoved
method of your service as follows:and have an broadcast receiver which will again start a service. I have tried it. service restarts from all type of kills.
inside onstart command put
START_STICKY
... This service won't kill unless it is doing too much task and kernel wants to kill it for it...In your service, add the following code.
The reason for this is that you are trying to use an IntentService. Here is the line from the API Docs
Thus if you want your service to run indefinitely i suggest you extend the Service class instead. However this does not guarantee your service will run indefinitely. Your service will still have a chance of being killed by the kernel in a state of low memory if it is low priority.So you have two options:
1)Keep it running in the foreground by calling the
startForeground()
method.2)Restart the service if it gets killed. Here is a part of the example from the docs where they talk about restarting the service after it is killed
All the answers seem correct so I'll go ahead and give a complete answer here.
Firstly, the easiest way to do what you are trying to do is launch a Broadcast in Android when the app is killed manually, and define a custom
BroadcastReceiver
to trigger a service restart following that.Now lets jump into code.
Create your Service in
YourService.java
Note the
onCreate()
method, where we are starting a foreground service differently for Build versions greater than Android Oreo. This because of the strict notification policies introduced recently where we have to define our own notification channel to display them correctly.The
this.sendBroadcast(broadcastIntent);
in theonDestroy()
method is the statement which asynchronously sends a broadcast with the action name"restartservice"
. We'll be using this later as a trigger to restart our service.Here we have defined a simple Timer task, which prints a counter value every 1 second in the
Log
while incrementing itself every time it prints.Create a Broadcast Receiver to respond to your custom defined broadcasts in
Restarter.java
The broadcast with the action name
"restartservice"
which you just defined inYourService.java
is now supposed to trigger a method which will restart your service. This is done usingBroadcastReceiver
in Android.We override the built-in
onRecieve()
method inBroadcastReceiver
to add the statement which will restart the service. ThestartService()
will not work as intended in and above Android Oreo 8.1, as strict background policies will soon terminate the service after restart once the app is killed. Therefore we use thestartForegroundService()
for higher versions and show a continuous notification to keep the service running.Define your
MainActivity.java
to call the service on app start.Here we define a separate
isMyServiceRunning()
method to check the current status of the background service. If the service is not running, we start it by usingstartService()
.Since the app is already running in foreground, we need not launch the service as a foreground service to prevent itself from being terminated.
Note that in
onDestroy()
we are dedicatedly callingstopService()
, so that our overridden method gets invoked. If this was not done, then the service would have ended automatically after app is killed without invoking our modifiedonDestroy()
method inYourService.java
Finally register them in your
AndroidManifest.xml
All of the above three classes need to be separately registered in
AndroidManifest.xml
.Note that we define an
intent-filter
with the action name as"restartservice"
where theRestarter.java
is registered as areceiver
. This ensures that our customBroadcastReciever
is called whenever the system encounters a broadcast with the given action name.This should now restart your service again if the app was killed from the task-manager. This service will keep on running in background as long as the user doesn't
Force Stop
the app from Application Settings.UPDATE: Kudos to Dr.jacky for pointing it out. The above mentioned way will only work if the
onDestroy()
of the service is called, which might not be the case certain times, which I was unaware of. Thanks.You can use
android:stopWithTask="false"
in manifest as bellow, This means even if user kills app by removing it from tasklist, your service won't stop.