My app makes a websocket connection to a URL using this library. Everything is working fine. The app is a communication app (sends and receives messages). When the app goes to the background (pressing the home key) the websocket connection still works and the user receives push notifications for new messages.
The problem is that, when the app is in background, after some amount of time, the websocket connection disconnects automatically. Now this time interval is different each time (sometimes 5 seconds, sometimes 5 minutes).
Now the problem is not with the URL (no idle time/timeout issues - believe me, it works fine on other platforms). So I am looking for possible reasons for this behaviour so I can fix the problem.
How could the websocket connection be disconnected when the app goes in the background. Also, should I run a continuous background service as a remedy?
PS: There is no service in the app right now. The library is supposed to let the websocket connection running when the app goes to the background.
The issue is that the library you are using does not stop the connection when the app is backgrounded... however, Android may kill the process.
A Service exists specifically to prevent that problem. If you implement it in a Service it should solve your problem.
A word of caution: just because you can do this it does not mean that you should do this. Be careful about memory and battery usage when you implement a Service. They are intended to run in the background indefinitely - and you can make some users very unhappy if you have CPU/battery intensive code, or Android may kill the Service if it consumes too much memory.
Related
I have written an VPN using android's VPNService and it works perfectly. When I run it, it creates a foreground service and sends all traffic through my VPN server. It also has an internal reconnecting mechanism to reconnects VPN server if it disconnects for any reason without stopping service itself.
I like to have this VPN service working all the time. But my problem is that this VPN service is stopped occasionally after a completely random period(sometime it takes just 10 minutes, but other times it works for 2-3 days before stopping).
Since the stopping time is completely random and I cannot find any place in code that creates this situation (I have been debugging for weeks), I thought maybe android OS itself stops my VPNService for some reason. I wonder if there is a way to detect if system has stopped my service from outside or not. Any idea?
Unfortunately, Android OS still can terminate the service in low memory and possibly other situations, even if it's a background running service !
It is not only Android, but all Mobile Operating Systems optimize RAM usage by killing background apps.
This is done so that the foreground app can be given top priority. It ensures smooth functioning of the current app and reduces load on the system.
There's are two approaches as mentioned in this post: Background Service getting killed in android
If you are implementing the service, override onStartCommand() and
return START_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.
I had this issue previously and I've solved it by creating the service running forever even if it's killed manually or from the system it recreates itself.
I am developing multiplayer game using Socket.io library. it Works Well.
But, in android 7.0 and above, system automatically suspend all network work when my app is in background. (And I must need to keep alive my socket connection).
I research about it as described here.
but, i can't understand. So, Please provide solution for that.
Unfortunately there's bad news and some good news for you on this.
Bad:
Since android marshmallow and above, there's a concept of a doze mode. If the device stays put for some time (can't confirm the duration for this and not disclosed by google), the device will go into doze mode and will suspend all network activity. There will be short maintenance windows where in you will be able to do syncs and stuff. Small workaround, do not target 23+ apis, i say small because i have observed this to not work on some phones. Another way to potentially bypass this would be to whitelist your app from battery restrictions but according to google guidelines, i don't think your app will qualify for that.
Worse news is that start from API 26, background services will also get suspended completely when app is totally backgrounded and has no visible component (a notification or a foreground service etc...). So oreo will be worse.
Good:
You might not really want to constantly keep the socket open. Instead opt for bursts of syncs. I personally have a job run every 30 - 60 mins or so to try and sync up.
You can leverage the JobScheduler apis and it will automatically handle the doze modes and stuff and you can make them run periodically when there is internet connection. While the job is running, you can connect to your server, do your thing and shut the socket. This is what google wants and is pushing all devs towards.
UPDATE 19-Apr-2021
WorkManager is the new and the best way to deal with doze mode and background limit restrictions.
Another alternative would be to have a foreground service with an active notification displayed which would constantly be connected via your socket. This will be visible to the user and it will not only annoy them that you are constantly using their data, it can also be bad for the battery. Alternative to this again is using the job scheduler to schedule and run a foreground service periodically so as to be transparent while also syncing your data every once in a while. The latter approach is what WhatsApp does, they have a job running which syncs all incoming messages with a foreground service once in a while.
In Short:
You will not be able to keep it alive always. You can try doing it in bursts using one of the methods that i described and know currently (maybe there are other alternatives that i don't know, i have tested these and they work) You will have to compromise, sorry.
I developed a VOIP app on Android which is working pretty good since we changed from GCM to our own push service by having a sticky background service running with a TCP connection. I made my own solution instead of GCM because realtime pushes are not really working.
Like I said normally everything works pretty nice and my service works most of the time but there is one big problem I can't seem to solve: When somebody uses games or apps with a lot of RAM usage my service gets killed and killed over again(it gets restarted through a alarm which detects it is not running anymore).
So how am I supposed to have the service running with a ongoing connection when the system kills me all the time? The only thing I can think about is to have a very fast Alarm like checking all 15s if my service is still running which seems like a bad idea.
I am building an android IM chat app which needs to keep a long connection to the server. However, on some android phones (not all android phones), when a user locks their phone the app and its thread (running in Service) are paused and the chat app can no longer receive messages.
I want to know how to solve the problem?
You should use a Service. There is never a guarantee that it will always stay running, but unlike activities, services are designed to run in the background. They're more likely to stay running if you request foreground status.
You can find more information about services here.
I need to keep an open connection in the background, even when the app is not running. It's not possible to use GCM because the connection will be in the same LAN as the server, and the device may not have a working Internet connection.
The connection will be some kind of local Push, so the device will just get some short relevant data from time to time (in addition to the keep-alive messages).
My use case is quite specific so I can consider that the battery is not an issue. I may show a huge red warning saying that enabling the feature will drain the battery, or just disable it if the device is not charging.
On the other hand, is quite important that the process with the connection is not "randomly" killed by Android.
I thought about implementing this with a service, but I would like to hear opinions from someone else. Maybe there is a better way to do it, considering the constraints mentioned before.
"even when the app is not running"
That means that your app is not running, and it doesn't have a process. Without using a third part app (such as the GCM service) that awakes your app, nothing can reach you.
You can, however, have a service that remains active and keeps a connection to a server (say, for instance, an XMPP server) to receive notifications and wake up this or that activity.
You can also do that in a separate application.
You can add robustness with a regular watchdog started by the alarm manager, for example.