I have implemented a background Service that is running in the same process as my app. My problem is that when the app is closed (tab on windows button, then swipe app to the left to close it), it causes the whole process to close and the Service to stop working as well.
On the OnStartCommand() callback in the background service, I return START_STICKY.
It takes about 5 seconds for the process to appear as closed (0 processes and 1 service) on app settings page as below
Currently to overcome this problem, in my activity OnDestroy() callback I set an alarm-manager to start my service again after 10 seconds -giving enough time for process to fully close before opening it again. This solution works to an extent, but it's not what I want. What I really want is for my Service not to close from the first place.
I have looked at the option of making the Service in a separate process, however, I then found major difficulties in using variables and functions on the service class and stuff since they are now in separate memory stacks.
I know about the foreground service solution but unfortunately having the that notification stick there all the time is very intimidating.
Is there any good solution to keep the service running even when the user closes the app ?
Related
I'm developing a player app.
For this reason, it uses a foreground service to handle the playback.
Until recently the service was bound to my activities.
This is not the case anymore.
Since then, some specific devices (mostly Pixel 1/2/3) have been killing my app 1 minute after the screen has been turned off
The service is a foreground service not bound to anything.
Why would the device kill it?
As soon as the app is excluded from the device-optimized apps list the issue is solved
I'm not providing code, because I'm just trying to understand if this situation makes sense and if so what should I do to prevent this
BTW the app is using a receiver to act on Screen_ON/OFF messages. That's how I can see in the logs that the player service onDestroy() method gets killed exactly 1 minute after the screen has been turned off
what should I do to prevent this?
The key point here to keep the service alive is as said in official documentation :
While an app is in the foreground, it can create and run both
foreground and background services freely.
so, we can conclude that keeping the work in foreground and visible to the user has very minimal chances of being killed. And to do so we need to know that how android gets the idea that this process is in foreground ?
Here are the criteria's at which a process is said to be in foreground:
It has a visible activity, whether the activity is started or
paused.
It has a foreground service.
Another foreground app is connected to the app, either by binding to
one of its services or by making use of one of its content
providers. For example, the app is in the foreground if another app
binds to its:
-IME Wallpaper service
-Notification listener
-Voice or text service
If none of those conditions is true, the app is considered to be in
the background.
If none of the above criteria is fulfilled by your app process then thats the reason of your service being killed.
You can read more on this topic here :
Foreground service being killed by Android
I want app to start a timer at certain point and run for four hour and is displayed in UI.
Now problem with using service is that it closes if app is closed. (Same with Handler)
And if I use system time than if someone changes system time, 4 hours extends
So is there a better way to implement such task?
You can make services not close when the activity (visible) is stopped. One way to guarantee it stays alive is to make it a foreground service (will show a notification). But if you don't make it a foreground service it will still last for some time unless your device is running out of battery for example.
In your case, to make it last four hours, perhaps use the foreground service alternative (showing a notification)
Foreground service
Vogella foreground service
AlarmManager should help see page http://developer.android.com/reference/android/app/AlarmManager.html
I have started a service from my application and from that service a worker thread is started .I want my service to run even application goes background and until the user kills/exits the application.
But some cases my service got killed due to low memory ,then used sticky service or making the app to foreground to restart the service.
My issue is I dont want to lose the data between service ending and restarting time ,so is it possible to start another thread from service ondestroy method, but in this case how we can control that thread.
Please let me know is it the right approach ,and is this usecase achievable
I want my service to run even application goes background and until the user kills/exits the application.
This is not possible. The user can always get rid of your app, via Force Close in Settings, or via some device's version of the recent-tasks list.
But some cases my service got killed due to low memory
No, your process is terminated for low memory.
My issue is I dont want to lose the data between service ending and restarting time ,so is it possible to start another thread from service ondestroy method
No, because your process is being terminated.
Please let me know is it the right approach
Probably not. Very few apps need a service that runs constantly, which is why Android, and its users, go to great lengths to control such services. I would recommend that you try to find some solution to whatever your problem is that does not need a service running constantly.
How do I keep a service running, when all activities of an application are viewable. and close the service only when I leave the app?
Is there a way to start a service in one activity of an app and stop that same service in another activity of that same application?
I don`t want that service to continue running when the user leaves the application.
There is really no concept of 'application' and leaving it. What happens if open a link from one of your activities, launch the browser to view it, then come back via the back button? Did you really leave the app?
What does your service do? Do activities bind to it? If so, it will be automatically shut down after the last client unbinds. If not, it should shut itself when it has finished doing it's work (Cf. IntentService). If it doesn't fit either of those patterns, maybe you don't need a service at all, just some background thread(s)?
Edit (based on comments below):
For a service running a media player, the usual way is to have an ongoing notification for the service that lets the user bring up an activity to control the service. Or have buttons on the notification in JB to achieve something similar. Additionally, if you make the service a foreground one, that will give it higher priority and it is less likely to be killed if resources are low.
I have a service that is maintaining a socket connection to a game server. The game needs frequent two way communication to the server, so this connection should be kept open as long as the app has the foreground. However, since keeping the connection open is battery intensive we'd like to be as nice as possible and as soon as the app leaves the foreground (ie the user returns to the home screen) we would kill the connection.
This is all pretty close to working, but we're running into a couple small irritations. Whenever the game changes Activity's (such as to the preference activity) the connection drops. Now we could have each activity drop the connection onPause and and start up the service responsible for this, but that seems less than optimal since it will cause unnecessary dropping and reconnecting. Binding the service stop to the onStop method also seems way less than optimal since the connection will stay alive long after the user leaves the game.
What we're looking for is a way to start up a service at some point soon after out initial activity starts and keep that service running as long as the application is in the foreground. And as soon as the user leaves the application have the service shut down.
If you only need it to run while the app is in the foreground (i.e., one of it's activities is displayed), you don't really need a service. Make your connection manager class a singleton and count the number of activities that are using it as described here: https://groups.google.com/forum/#!msg/android-developers/yxOzuMGlcSo/yd-pkau0zzAJ
Services in Android are used when you need to run without a UI, so not really a good fit for your use case.