We have stumbled upon an issue in Android 8.1 and above that, we haven't seen before, and that, unfortunately, makes our app less convenient for our users. Background sticky services in Android 8.1 and above isn't re-started when user swipe kills the app.
In Android 8.0 and below, there are high promises for services to be always available in the background, especially for services that are implemented as "sticky services".
To sum it up, the non-sticky services is not re-launched during a swipe kill in the recent app list. For sticky services (application host together with the service), the app is re-launched shortly after the kill. And foreground services apps are actually never killed, even during a swipe kill.
This works as intended and just fine in Android 8.0 and before. So, after a kill swipe, the app process is re-created within a short time, and then onCreate and onStartCommand is called, starting up the service completely again.
But from Android 8.1, the onStartCommand call is omitted. So instead of getting onCreate and OnStartCommand, we get onCreate and OnDestroy. This effectively does not make the service active again. Needless to say, we cannot manually start our own service in onCreate either.
I think the following article shows the differences quite clear (and with functional code) between non-sticky services, sticky services, and foreground services.
In Android 8.1 and above, the onStartCommand call is omitted (and therefore the service is not restarted). So instead of getting onCreate and OnStartCommand, we get onCreate and OnDestroy during app re-creation.
Also, we would not prefer to have a visible app icon at the top persistent all the time (as when using setForeground service), and rather just let it work in the background without bothering the user too much.
Don't Optimise Battery may work your service to run properly
you can also use AlarmManager to restart service after a fixed time
it could help click
from android 8 shouldn't be started service in background, you must start service as foreground.
my suggestion using android workManager supported by Google link
workManager is a stable and reliable library for working with service and schedulers task
Related
I have an Android Library with a service, which I implemented using AIDL. I want a single instance, cross application to be used with other apps. So I have a base app with the service and I managed to make the library for other apps to use the same instance.
My problem comes when I close all apps using the service, because for every app, the on destroy unbinds from the service, but the service is still running.
Also, I'm only using the service by binding, not by startService().
I checked through android studio that the service is running after closing the apps, and the counter I have on the service for each bind/unbind call is 0!. I increment the counter when there is a call to bind, and decrease for calls to unbind. My only way to make the service stop is by opening the base app, which has the service defined and closing it.
Edit: Also noticed that onBind is being called only once, even for other apps that are binding, but the reference for all those apps is still the same service, they share the same information and only one Service is shown in the android studio.
Edit: I've also observed that if one of the apps using the service is the base app, if I close it, the service dies and another one is started, the other apps don't notice the change, they keep using the service as if nothing happened, which is understandable because it's a remote service.
What is happening and what can I do about it?
For the two points being questioned:
I was able to verify what CommonsWare said that the process in which the service is run is still up, but the service itself is not. At first I had a thread running in the service after every app unbound, but after making sure it wasn't up in the end made the service be destroyed.
The second issue, regarding the service being destroyed while still bound with other activities was solved by seeing this link which describes a bug in android that kills services when it shouldn't. My case was simply solved by making my service run in the foreground, which I didn't know was possible.
After some tests I verified the service is still intact as long as any app is bound with it, and that the service indeed is destroyed correctly after no more app is bound.
When I implemented my widget a couple years ago, I used this advice from the App Widgets page on the development site (still there): "If your App Widget setup process can take several seconds (perhaps while performing web requests) and you require that your process continues, consider starting a Service in the onUpdate() method." I did this and it worked like a charm when built for SDKs up through 25.
It also worked on Android 8.0, but as soon as I targeted 26, the app started crashing in the onUpdate method of the widget provider when issuing the startService call. The error message had to do with trying to start a background service from another background service, and although I tried a few things in the service definition in the manifest I couldn't get it working.
I ended up doing a workaround when I decided that I didn't really need to update the widget from a service, so now just do the update directly in onUpdate. Services and background/foreground issues are something I've not messed with much, but I'd still like to know if there is a way to have kept using a service to update the widget.
in Android O, we have a new background limitations. When you're trying to startService(), you will get IlleagalStateException, so now you should use startForegroundService(), but if you start service by this new method, you will get RemoteServiceException. To avoid this exception you have 5 seconds to make startForeground() after startForegroundService(), to notify user, that you're working in background.
So, where is only one way in Android O:
context.startForegroundService(intent)
And in service onCreate() make something like that:
startForeground(1, new Notification());
UPDATE
So as i assume, some manufacturers have backport on Android N these new background limitations, that's why you can get same exception in Android N.
Without a Minimal, Complete, and Verifiable example, it is difficult to help you. Depending on what you had, you could have:
Switched to JobIntentService, particularly if your old service was an IntentService and you did not mind the possibility of a several-second delay in the work being started
Called startForegroundService() on Context (instead of startService()) to start your service, and in your service call startForeground(), to make your service be a foreground service
Called getForegroundService() on PendingIntent (instead of getService()), and in your service call startForeground(), to make your service be a foreground service
On Android Oreo, If my app starts a service while in foreground and then I close my app, will the service be killed later on? or will it stay alive?
From this video post it seems like the service will be killed if the app is in background, https://www.youtube.com/watch?v=Pumf_4yjTMc&t=198s
However, while testing, the service is quite alive. Will appreciate any productive feedback.
The service gets killed eventually
When an app goes into the background, it has a window of several
minutes in which it is still allowed to create and use services. At
the end of that window, the app is considered to be idle. At this
time, the system stops the app's background services, just as if the
app had called the services' Service.stopSelf() methods.
https://developer.android.com/about/versions/oreo/background.html
The service´s call and all of your current aplication´s process will be killed if you close or destroy your application, cause all of these process are linked to your app´s lifecycle, if the lifecycle is closed, killed or crashed, all of the processes go to the same end.
Thanks for your answers! Appreciate your responses. It Was my bad as I switched the work branch that wasn't targeting API 26.
I think, it's worth mentioning that the above restriction is only applicable if the app is targeting api 26 (Android O).
I have started moving to Job scheduler, and that seems to be working on Android O.
I have an Android application which supposed to be active in the background all the time. I've built it as normal Android application. It works pretty fine, however, sometimes it stops by itself (or by Android OS) and have to re-run it. It's not because of an error caused, this is because it's a normal application, perhaps.
How do I make work all the time in the background?
UPDATE:
the application has GUI.
Android OS may terminate a process at any given time due to memory constraints, you can learn how Android manages memory here. As #Karakuri mentioned starting a service would make it much less likely to be terminated, another plus for using service is that even in the event that it is killed the OS would try to resurrect at a later time when memory constraints permits:
Note this means that most of the time your service is running, it may
be killed by the system if it is under heavy memory pressure. If this
happens, the system will later try to restart the service.
You can learn more detail on Services from the Android dev site.
Create a Service and call startForeground() to make it a foreground service. It doesn't prevent it from being killed, just makes it less likely as Android will try to keep it alive longer than non-foreground services. Note that you need to place an ongoing notification with an icon on the status bar when using a foreground service.
Assuming you are using a Service. If you return START_STICKY from onStartCommand() of service, then even if android has to terminate that service, it will be re-started as soon as the resources are free.
I notice that applications like Skype use a service which basically runs 24x7, without getting killed at all. You cannot even manually kill it using task killers ( you can kill them by going to running services and kill service ). How is this implemented?
I find that in Android 2.3, my service gets killed after running for sometime. onDestroy() is never called even if I start the service with START_STICKY. However this works fine on my 2.1 device, that is the service doesnt get killed.
Thanks
How is this implemented?
Based on the Skype screenshots that show a Notification icon, then they are most likely using startForeground().
I find that in Android 2.3, my service gets killed after running for sometime.
That is perfectly normal.
First, most Android applications do not really need a service that "basically runs 24x7". Users do not like such services, which is why task killers and the Running Services screen and the auto-kill logic in the OS exist. The only reason a service should be running "24x7" is if is delivering value every microsecond. VOIP clients, like Skype, will deliver value every microsecond, as they are waiting for incoming phone calls. Most Android applications do not meet this criterion.
If your service is running constantly, but for a user-controlled period (e.g., a music player), startForeground() is a fine solution.
Otherwise, I would rather that you find a way to eliminate the service that "basically runs 24x7", switching to a user-controllable polling system using AlarmManager, so your service is generally not in memory except when it is delivering value.