Android Background Service Is Restarting When Application Is Killed

Restarting the app after process has been killed by the OS

The only solution i found that works for me is putting this code in a base class for activities to inherit:

private static boolean isFirstOnCreate = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResource());

if (isFirstOnCreate && savedInstanceState != null) {
startActivity(getPackageManager().getLaunchIntentForPackage(getPackageName()));
finishAffinity();
}
isFirstOnCreateInvocation = false;

Android Service restarting when application is killed

After your clarification regarding the killing:

You probably want to run your Service in a different process than your Application, which you can achieve by such a declaration in your manifest:

<service
android:name=".ServiceClassName"
android:process=":yourappname_background" >
...

Use the same android:process attribute for any receiver declarations in your manifest.

If you only want to receive events which can be declared in the manifest, you can consider using an IntentService, which will almost never be visible to the user due to its short activity timespan. However, if you need to listen to events which can only be received when you register receivers programmatically (in which case, obviously, the receiver clause in the manifest makes no sense) then you cannot do anything against a user (or one of the "smart app killers") killing your service. The advantage, still, would be that users hopefully understand that your app can be killed, while your Service can't (if they want it to do something).

Additionally, you can bring your Service to the foreground.

Android Service: Restarting once killed or removed from task stack from phone(Clear All) tasks

If the user performs a "force stop" on your app, your Service will be killed and there is nothing you can do to stop it. There is also nothing you can do to restart your Service automatically because the user has told Android that it doesn't want your app to run anymore. The user must manually restart your app.

If you remove your app from the "list of recent tasks", Android will kill the OS process hosting your app. Assuming your Service is also running in this OS Process, it will also be killed. In this case, assuming that you have returned START_STICKY from onStartCommand(), Android will restart your Service in a new OS process.

There are certain devices (Xiaomi, Huawei, some other Chinese phones, some LG and Lenovo devices) where your app must be manually added to a list of "protected apps" or "apps that are allowed to run in the background" in order for Android to restart your Service automatically. On these devices, Android will not automatically restart your Service even if you have returned START_STICKY from onStartCommand().

See also Situations when a Service's onDestroy() method doesn't get called?

Service restarted when Application Killed

This is a re-post from my answer here: https://stackoverflow.com/a/39169603/6761960. I'll re-post for convenience.

The app and the service live on the same process, which means when the app is killed so is your service. Changing the return value of onStartCommand doesn't affect this process. It simply tells the Service to either start/stop when you tell it or when it's finished doing what it needs to.

To change the Service so that it's killed separately and assuming it's a started service rather than a bound service due to the use of onStartCommand, specify a process name in the manifest for that Service.

From the Process and Threads Developer Guide:

The manifest entry for each type of component element— <activity>, <service>, <receiver>, and <provider>
supports an android:process attribute that can specify a
process in which that component should run. You can set
this
attribute so that each component runs in its own process or so
that some components share a process while
others do not. You can also set android:process so that
components of different applications run in the same
process—provided that the applications share the same
Linux user ID and are signed with the same certificates.

Android might decide to shut down a process at some
point, when memory is low and required by other
processes that are more immediately serving the user.
Application components running in the process that's
killed are consequently destroyed. A process is started
again for those components when there's again work for them to do.

From <service> in Manifest File:

android:process

The name of the process where the service is to run.
Normally, all components of an application run in the default process
created for the application. It has the same name as the application
package. The element's process attribute can set a
different default for all components. But component can override the
default with its own process attribute, allowing you to spread your
application across multiple processes.

If the name assigned to this
attribute begins with a colon (':'), a new process, private to the
application, is created when it's needed and the service runs in that
process. If the process name begins with a lowercase character, the
service will run in a global process of that name, provided that it
has permission to do so. This allows components in different
applications to share a process, reducing resource usage.

Using this method, your Service and your app will have two different process resulting in them being killed for separate reasons. However, this doesn't guarantee it still won't be killed. You should design, expect, and be willing to have your Service be killed.

Also, due to the fact your app is a music app and the use of your Service is something that the user is actively engaged in, creating the Service is an acceptable reason to give it foreground priority using startForeground. But, again, this doesn't mean it won't ever be killed.

How to restart service after the app is killed from recent tasks

Override onTaskRemoved() in your service and use alarm manager to start the service again. Below is code from our app that does the same and works fine:

@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);

Log.d(TAG, "TASK REMOVED");

PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
}

As you may want to send location periodically even in the case if the service gets killed on low memory (or for any reason), I suggest you to handle the uncaughtException to restart it after N seconds. This is how we have done in our app that works perfectly:

private Thread.UncaughtExceptionHandler defaultUEH;
private Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {

@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.d(TAG, "Uncaught exception start!");
ex.printStackTrace();

//Same as done in onTaskRemoved()
PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
System.exit(2);
}
};

Note: I THINK and I remember I verified it on Kitkat that START_STICKY does not work on Kitkat and higher API levels. Please verify this for yourself.

MORE:
As you do loc sending periodically, you may have to consider the deep sleep mode. To get things work in deep sleep, use WakefulBroadcastReceiver combined with AlarmManager. Take a look at my other post How to use http in deep sleep mode.

UPDATE:
This solution does not work (in fact need not to work) if user "FORCE STOP" the application from Settings. This is good in fact as restarting the service is not a good way if user himself wants to stop application. So, it is fine.

Android: Service is killed and restarted after a while

If you are using a background Service with a scheduled task, it could be killed by the system. The only way to prevent the killing is a foreground Service. Quoting the documentation:

A foreground service is a service that the user is actively aware of and is not a candidate for the system to kill when low on memory.

You have to call the method startForeground() inside your Service using a Notification to show it. For further information you can check: https://developer.android.com/guide/components/services.html#Foreground

By the way, I recommend you to use the new JobScheduler api above api 21.
https://developer.android.com/reference/android/app/job/JobScheduler.html

Service restarted on Application Close - START_STICKY

Short answer: you can't. Every Android app can be killed by the system or by the user when the system claims memory or the user swipes out the app from the recent apps list. This is an Android design and all apps must adhere to it. The only (small) improvement you can have is setting the service as a Foreground service:

where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)



Related Topics



Leave a reply



Submit