I'm developing a simple multi-player Android game that communicates with its Game Server using Java Sockets. And to create non-freezing UI, I decided to make Service class in Android app to communicate with server over the Socket connection. Data exchange is done in JSON format.
Now the thing is, during entire game play, a single Socket connection will persist, and data exchange will be done from-and-to the server, but based on events happening on game client running in Android.
Eg; When user taps a button, some data is sent to server and server responds back with some data, until then, client will wait, when data arrives, UI on the activity will be updated, and client will again perform some action, and again that data will sent to server, and so on.
While the client is waiting for data from the server, I'll disable the controls on Activity such that user doesn't perform any actions until data arrives from server, and I'll also show waiting dialog on Activity to let user know that app is not frozen and is waiting.
Now, as Android service primarily works with onCreate(), onStart() and onDestroy() methods, I believe it executes something in background without any user intervention. So in case of my app where I need some input from user (or wait until user provides it) to send it to server, how I'll be using Service class in this case? Also, is there any other option I have apart from using service in such a scenario.
Also, note that I have two activities in my app which will be communicating with the server using single Socket connection.
Related
I have an Android application that has a screen for displaying information about any user of the service for which mobile application was developed. Users are able to subscribe to other users on that screen.
Current solution with Rx and Retrofit works fine but when user leave the screen I clear disposables and then the http call under the hood of Retrofit is being canceled. So if user leaves the screen his operation on it (such as subscribing or likinng/disliking) get lost.
I want to keep that requests which modify some data (usually POST-request) and send them until backend of my application will receive it and send a response. Moreover I want to persist that request on disk to survive the app's process death. It means that if user leaves screen and system kills my app then after it launched again it will perform an attempt to send saved requests. Of course if there is an internet connection.
I wonder if out-of-box solution for that purposes exists. I appreciate any advice.
Workmanager can be used to schedule this kind of request.
I have a service which send some messages to server, I want user to keep track with failed messages allowing him to resend them any time.
I used an eventbus util with rxjava to post updates to ui, it works nicely when app is open, but when app is closed ui doesn't receive eventbus events.
I tried to post events to a local list saved in shared preference, and read data from it when user opens app, but it seems that not a good solution.
In Android, i have a socket keeping real-time communication with the server.
This app socket is being controlled by a service, that starts on boot and / or whenever a request is being emitted by the app.
Because I cannot depend on Google PlayStore, I fully control the sending + receving of push-messages manually.
Whenever a new push-message arrives from the server, the socket-service sends a local broadcast message and the listening activities can follow there own action.. If no activities are found, a default android notification is given to the user, saying '[ap] You have {n} new message(s)'...
This has its stability problems (the service can be shut down by the OS when low on memory for example) but its okay.
Now, consider the following:
I have multiple activities that listens-for and shows a count of unread messages.
HomePage
ConversationsOverviewPage
'The' conversation page (chatpage)
Each activity can be on the foreground, but can also be in memory for when the user back-presses and goes back 1 activity. So in Theory, there can be a situation where you want to update different/multiple activities at once.. This prevents having to 're-load' the unread messages from the server when the user gets back to a 'savedInstance'. So the broadcast pattern works best I think.
What is best practise for keeping global track of unread messages, while minimising the server trip on every activity instance:
Very simpel: Make a server request on each and every activity instance, and write update code again for every activity. But this results in the user seeing a delay, as it takes a second before the app receives data from the server and show the 'unread-messages' balloon.
Simpel: Have a global class.. Holding the unread messages for each conversation, But I feel this can give problems with data being incomplete.. Especially when the app is not 'active'
My old vote: Have another service thats keeping track of the unread messages, that starts on boot (just like the socket).. Only when the service starts / boots, it will requests all unread-messages data from the server. Each activity can than 'ask' for the unread-messages data and don't have to worry about it anymore.
But this could be overkill?
My new vote: Keep the socket-service, and add a separate class to this service.. That holds the unread-data.. But this also does not feel to be right.. As the activity would have to ask the service something out-of-scope.. Its not the sockets concern to manage unread messages (separation of concerns), right?
Any thanks from experienced developers is much appreciated!
Third options is ok. Not sure where is overkill exactly. Obviously you shouldn't download all unread messages on every boot or socket reconnection. The most important rule of thumb is to load data when the app really needs it. Few moments about how I've developed about the same app:
there is socket Service which handles connecting, disconnecting, sending data(messages) and receiving data.
there is Notification manager which receives events from SocketService. It saves new data which comes from server and decides which broadcast notification should be sent.
when socket is connected it receives state data from server:
dates(timestamp) of last update for every chat. For instance if local database contains that chat A was updated yesterday but freshly received data from server says that the chat A was updated few seconds ago you need to broadcast event like chat A has been updated since last connection and save update date. If there there is any activity which somehow show the chat A it loads(through http or whatever) new data.
last messages for every chat. The app just compares locally saved last messages and freshly received. If there is new one the app again broadcast event like there is unread message/messages from user x. If there is visible activity which shows updated chat it updates data otherwise the app shows notification.
So the basic flow of handling unread messages is next: connect to the server > check if there is data about unread messages > save new data to the local database > broadcast events about new data.
And I would recommend you to use GCM and socket connection simultaneously. GCM really helps to keep data updated. It wakes up a phone and sometimes delivers data when socket connection just could not be established due to network problems.
Detail:
I have developed an android native application on ADT.
App performs ADD , Search and update operations on SQL database hosted on Windows Azure cloud platform.
All the operations are performed by calling a Mobile Service built on Windows Azure Cloud platform.
Problem Description:
Every time I want to ADD a new record via UI of app, my app calls mobile service and get hang till the operation completes.
I want to do this operation but do not want user to wait for it to complete.
Additionally when there is no network, user addition should be kept in queue for later addition.
Ideal Scenario: I want to display Addition operation in pending status to user and make that as a background process till the time it completes.
Note: There can be many ADD operation going on by multiple users. Need to keep that in mind.
Please suggest options to do this.
Free to ask questions in case of any query regarding problem statement.
Thanks
Anshul
You have to use AsyncTask to do work in the background and update the UI for the User or Pop a notification in OnPostExecute which means background work has been done.
For Queuing when No Network:
You would have to user a Service with BroadCastReceiver which listener for Network-Connectivity. Once the BroadCast Receiver Receives that Internet is Connected, You can then start calling the mobile service.
But Let me add that the Queued Data has to be Saved so you would have to create a SQlLite database or save the Data to a file on the Phone, which you can retrieve the data from, when the BroadCastReceiver is notified that connection is back
My application can now synchronize some data to a remote server, and at the moment, it happens explicitly when my user clicks a button, the app shows a ProgressDialog and does the network operation in background with ASyncTask.
Now my client requires that the synchronization should happen on any data change. I cannot do it on the "foreground" like it's now, because it usually takes 5-10 seconds on mobile data connection, the app has to collect data from sqlite database, serialize it to JSON and send to remote web service.
Do I have to implement a Service that will receive a message from the application that it's time to do the synchronization? Or could I just move my ASyncTask to Application class and do the operation from there?
A service would be the best way to do this.