So, I am making an app, and I need to have a continuous background thread. It must not stop, the socket has to be always open, so don't please tell me to send data and close it, because I sent an auth request every time, and sometimes the app recieves data from the server. So, would AsyncTask be ok to use?
AsyncTask is used for Small fast Background task and not long Background Task for that you should use a Service or at least Thread.
Related
I need to make a request to an endpoint in the app startup, i really need to wait for the response to let the app continue running, so i need to make a sync request
how i can do it?
Any long-running sync request on the main thread will definitely trigger Application Not Responding (ANR) error.
It's highly recommended to move each IO (network, storage) operation to a worker thread. To achieve this you can use a stack of Kotlin Coroutines, Retrofit and Moshi.
To prevent the app from running until the network response, you should implement splash screen. Configure its lifetime as explained here.
i really need to wait for the response to let the app continue running, so i need to make a sync request
No, you don't. You need to provide some temporary UI that does nothing (like a loading spinner) while the async request completes.
Read up on coroutines for background work.
Making a "sync" request is just going to hang your app.
Currently the Android application I have taken in charge performs a "pull" on the server every minute to recover data and update a fragment with this data. Obviously this does not work when the device switches to doze mode. So I decided to use FCM as Google recommends.
Constraints :
The user needs to know that new data is available even in doze mode.
To not change the application too much, I do not want to send the data in the firebase message but rather send an https request to the server when I receive the fcm message.
The fcm message must:
Advise the user that new data is available with a notification.
If the user presses the notification OR returns to the application after turning the screen on, the https request must be triggered and fragment has to be updated.
I will add that it must be triggered at the latest when the user returns to the application.
My solution for now
I used a data message with a high priority instead of a notification message because a notification message need the user to tape the notification to trigger action.
In onMessageReceived :
I send the notification that redirects to my application.
I send my request to the server and update my application.
Disadvantage of my solution :
If my app is killed by the system while the screen was off what's going on?
My request has a time limit to complete when the phone come out of doze mode.
Questions :
Is this solution the best possible ?
Is there another way to proceed?
Perhaps could i schedule a task that runs immediately when user resume my app in onMessage received ? But i dont know how to do that.
Use WorkManager to schedule the background work to run immediately. It will also retry until your code indicates that it's successful.
I answer myself to close the subject and hope it can help someone !
After a night ... I definitely do not like the workmanager solution. Even if in practice it can work I do not like to use APIs for unplanned uses. If google tells me that it is not garanty to launch task immediately, they are (much :)) better than me and I believe them!
In this case, I think that my task may be postponed, for example because the OS wants to group calls with other apps. There may be internal conditions i dont know about.
Especially since I found a much simpler solution.
In onMessageReceived, I use a simple boolean indicator.
In the onResume of the activity I want to update I read this indicator and I launch my request if true for example.
I no longer need a scheduler, and after all if it is not done 100% reliable, it does not matter :
If fcm could send me a message there is a lot of chance there is a network when the user turn on the screen.
Even if there is none it is not very serious since I can warn the user who can proceed otherwise (by phoning for example !!!!)
I was reading about background service limitation in Android 8 and from what I read it seems that you can't run your service in the background for a long time. This seems reasonable but because I use background service to keep connection to server - currently pooling new stuff, sending location and responses I am a bit confused. The responses are OK, I can respond only when interacting with the app, but the pooling new stuff is problematic because it needs to get an stuff from server and if something new come present the user with a notification to respond to it.
If I understand it correctly I can use JobScheduler to schedule some job every several seconds. I can basically schedule the pooling. For the background locations, well there are those restrictions so only foreground service is an option to get updates in requested time.
I will be migrating to websockets and then the pooling is off, the connection to server will be persistent and the app will get updates from server, I was planing to do this in the background service so something would receive stuff from server everytime. However it seems I can't since Android 8. How would you solve this? Should I use foreground service for location and server connection? Or is there a better way to do background networking in an android app on android 8?
Thanks
Here are a few options for performing background work on Android O:
Use JobScheduler. You already seem to have a good grasp on this one- the downside is that it is periodic, not persistent.
Use GCM/FCM or a similar push service to push data to your app when it is relevant instead of constantly holding a connection to your server.
Use a foreground service. This will allow you to continue performing your background work without your app being in the foreground, but will put a notification in the status bar to inform your user that you are doing that work.
Before you select one of these methods, you should take a moment to step back and look at the data that you need from your server and determine why you need a persistent connection and whether the first or second options might be sufficient.
If you absolutely need a persistent connection to your server, the last option is your best option. The idea behind the changes in O is to still allow background work such as what you are describing, but to make it painfully obvious to the user that your app is doing so. That way if they don't think your data is as important as you do, they can take action.
I need to persist a socket connection when my android app goes to background.
Currently, the socket is started, read and written from its own thread. I also store a reference to this thread in a static instance of a class which means i have access to the thread's reference when my app is resumed.
I also don't need this socket to be persisted if the app is destroyed.
Now coming to my question, "Do i need to start a service to maintain this thread or can i just continue with my current design which is to store all such instances that i require when the app resumes in a static container class?"
The only advantage i found so far of using a Service is that the app might be one of the last few to be destroyed during low memory or similar scenarios by the OS (considering the service and the app reside in the same process).
Once your Activity is destroyed, your process becomes a candidate for being shutdown. Most likely, it will linger around a while and not get killed. But on a lower end device, with less memory, all bets are off. Go to Developer Options on your device and check "Don't keep activities ...". Exit the activity and see the outcome.
The workaround is to keep a Service active. Preferably with a notification icon so the user knows it's still running. That's exactly what I did with my music app to allow the audio stream to keep going even when the user switched apps.
On the flip side, a dedicated socket connection is going to use more battery and more of the user's data plan. If your socket is going to be idle most of the time, a better approach might be have the socket connection connect to the server only when notified via a push notification that there is data available.
I've been researching stackoverflow for days now, but can't seem to find a problem like mine.
I have an Raspberry Pi with a python socket server listening for incoming messages. Also I have a Android app which connects to it.
My idea was to create a "simple" music player on the raspberry pi with the use of the pygame module. You can see the Android app as the controller of the music player (Sonos like).
I already have a start, connecting the Android app with Raspberry pi is not the problem.
It's more how the communication between the two need to flow.
A few "solutions" I already thought about:
At the moment the Android app creates a socket object and connection in a new Thread then closes the Thread (so the Thread doesn't receive or sends messages, but the socket persists). When the user clicks a button (let's say to update the music list), it opens a new Thread then uses the already created socket object to send a command, gets a response and updates the UI then terminates the Thread again. And I do this for every action that needs to happen (play, pause, stop, etc.) With this method only the Android app has the right to ask for an action, because it's not constantly listening for server messages
So what if I would create a single thread which is in a constant loop sending a message and then getting a response: how do I interact with the loop from the main UI thread (like clicking a button). I thought about a synchronized List<String> MessageQueue where the main thread pushes a command and in the connection thread's while loops it checks if there are any messages that need to be send.
I made a little schema, how I had this in mind:
Schema (single thread with while loop):
single thread with while loop
Also the reason I chose sockets and not just a simple HTTP request is because later on want to update the UI so you can see real-time music playing (with the seconds updating and stuff like almost every musicplayer has, and who knows what more.
If you guys have any idea's, or know of any topics, example applications on how to create this then please share! If some things are not clear or are a little vague, feel free to ask/comment because I just started with asking on forums.
Example applications that use persistent socket connections with real-time communication are also welcome!
side question: would JSON be a good way to communicate between the 2 applications?
like this:
{
currentsong: "song1.mp3"
position: "1.30" // The current position the music is playing on the server
songlist: ["song1.mp3","song2.mp3","song4.mp3"]
...
}