Keeping threads and connection state in Android app using onSaveInstanceState? - android

I am developing a multi player game app for the android.
One of the participant is acting as the host (the one who created the game instance) and each of the other participants is connecting to the host using bluetooth.
My question is as follows, this host has some threads running in order to communicate and holds all the open connections. I've read that my Activities can be destroyed temporary and restored later and I should use the onSaveInstanceState mechanism for that. However, I am talking about an app that is acting as a "server" for the game and it has open connections and threads that serves the other clients, what happens to these connections and threads if the OS is deciding to destroy my activity? Are they terminated? If so what would be the recommended pattern in order to implement this properly, How can I keep a connection on the onSaveInstanceState bundle? it is not serializable. The same goes for the threads, do I need to recreate and destroy them upon destroy and when the activity is restored?? if I hold all this state in some static class that represents the game state? If I do so, will then the OS not destroy my threads/connections?
I looked at the sample Bluetooth chat that comes with the SDK and I so there's no handling of the onSaveInstanceState so it is very unclear what should I do.
Thank you!

what happens to these connections and threads if the OS is deciding to destroy my activity?
If you created those threads in an activity, you better stop those threads, or you will leak them.
How can I keep a connection on the onSaveInstanceState bundle?
You can't.
The same goes for the threads, do I need to recreate and destroy them upon destroy and when the activity is restored?
If they were started by the activity, then, yes, please.
if I hold all this state in some static class that represents the game state? If I do so, will then the OS not destroy my threads/connections?
Please put your server logic (threads, connections, server-side game logic) in an Android service. Please use startForeground() to keep that service going, putting a Notification in the status bar along the way so the user has an easy way to get back to the activity that allows them to stop your service.

Related

How to start and keep sockets connections accross multiple activities?

i'm having trouble finding a way to implement this:
I have an activity A from where i'll start 2x separate socket connections.
Afterwards i'll move to an activity B from where i'll go back and fourth with activities C and D. All 3 activities will exchange messages via the sockets.
Now from my understanding i need to create a service for each socket, but how exactly do i maintain both sockets open, without creating a new connection everytime i switch to another activity?
Also how do i keep the services running an "accept loop", prompting an action for the current activity the user is in?
thanks
You're correct that you should use a Service. A good rule of thumb is that you should use a service for any background processing that is not logically bound by the lifecycle of a single activity. (And use AsyncTask for background processing that is logically bound by the lifecycle of a single activity.)
But you don't need to create a service for each socket. You should create one service that does whatever it is you need to do with the sockets. There are a variety of ways your activities can interact with the service and pass messages or obtain references to its sockets, which you can read about in the documentation.

Android services - Sockets and streaming from one service to another on another phone

To put things simply, I'm writing a video chat application that's supposed to connect say, two Android phones. So far, I've managed to negotiate interactions between clients, until the point I've reached the part where I'm supposed to do the streaming of video (and later audio) data between the clients.
The problem is as follows:
I am trying to implement a service that will, once a person has decided to contact someone, be started from a ChatActivity, and that will negotiate streaming between the two clients, making the sockets and the data going between them completely independent of the events going on within the ChatActivity, except for the moment the conversation is over, where the activity is terminated for good, and with it the service.
However, my concern comes from the point that if the service terminates the sockets mid-conversation, I have the problem of having to renegotiate streaming between client and client.
As is probably obvious, my knowledge of android services is limited, at best, and any advice on the subject is welcome
My questions are:
Is it doable to create a service that will, bar unexpected crashes due to outside influences, keep such a connection active and running regardless of how many times the activity that displays the video from the streaming (ChatActivity) is destroyed and created?
Should I be going with a bound service or a started service for this, or some hybrid of the two?
If I were to somehow create a pair usable stream of video data from the service, one via internet connection other via camera, would I be able to send them back to the activity, and keep reconnecting them to the components, regardless of how many times they get destroyed and created during the lifecycle?
Despite my efforts, I haven't managed to find any examples of anything similar, if anyone has come across code that does some similar socket/service juggling, I'd be most grateful for directions.
Is it doable to create a service that will, bar unexpected crashes due to outside influences, keep such a connection active and running regardless of how many times the activity that displays the video from the streaming (ChatActivity) is destroyed and created?
The Service lifecycle, if started via startService(), is independent of the lifecycle of any of the activities. Activities can come and go, but a service can stick around for a while.
Should I be going with a bound service or a started service for this, or some hybrid of the two?
You will need to use startService() if you intend for your Service to run without any activities around.
If I were to somehow create a pair usable stream of video data from the service, one via internet connection other via camera, would I be able to send them back to the activity, and keep reconnecting them to the components, regardless of how many times they get destroyed and created during the lifecycle?
That's impossible for me to answer, without a complete description of what "a pair usable stream of video data" means.
That being said, you will probably want to consider an event bus like Square's Otto or greenrobot's EventBus, as they both have support for the UI layer receiving events on the fly (e.g., service just establishes communications) and retrieving on demand the last-sent event (e.g., activity needs to reconnect to the last stream).

Android app restarts Activity - what happens to Network IO in progress?

If I make a call to an external web service and the user rotates the device, the Activity will restart (I know you can handle it yourself but this is not recommended). I know I can preserve the state using onRetainNonConfigurationInstance().
The question I have is what happens to the inflight network IO after the Activity restarts? Does it continue, is it suspended or killed?
I am rather new to Android (iOS person) so the restarting Activity is rather odd.
Some network calls we make could be restarted, but checking out for a purchase is not one of them. How do I handle this so that purchases still work correctly? Assume I would use Asynctask (though I realize there are other choices such as Executors).
For network calls that need to maintain across activity restarts (e.g. purchase), consider using a service instead of doing it inside the activity.
If your connection is defined as instance variable inside the activity it will be destroyed/killed when the activity restarts.
Another alternative, but I would not recommend, is to implement an application class and maintain your connection there so it will be persistent as long as your app process is alive.
You should not be handling requests inside activities unless they are simple enough to fire off (i.e., do not require responses). The common use case is that you are interacting with a REST interface that you want to handle across multiple activities. The basic idea is to issue requests to the service and let it mediate the connection for you. Google IO 2010 had a good lecture that you can listen to.
Implementing the functionality inside an Application class is not recommended, as you will get strange behavior when your app is killed by Android when memory is tight.

Singleton or Service for socket connection

I'm new to Android development, i'm trying to port an IOS app to Android. Basically my App need to communicate with a server in real time with socket IO. It connect to the server and then handle the various message until the server finish to process the request.
In my IOS app i use a Singleton pattern to send the requests to my websocket server, and i use the same instance to delegate the server response.
In Android i was going to use the same pattern, with a callback object in my activity to redirect the user after getting a server response.
I need my app to keep the socket connection open until we got the right status from the server, even if the app goes in background.
Some people recommend using Service with Broadcast receiver instead of Singleton. Is it the best thing to do in my case ?
Using a Service is exactly what I have done for very similar purposes (doing socket communication for Bluetooth and TCP/IP applications) and think you'll certainly want to be using a Service if the communication should continue even when the user has closed the application.
A Service is essentially a means to run code on the UI thread (but of course you can then start off other threads within it) but without a user interface, unlike an Activity which has a UI associated with it.
If you were to try to do this in a static singleton class as you propose as an alternative, then I think the problem would be that you wouldn't have very good control over the lifecycle of it. If the user navigates away from the application, then my understanding is that it's up to the framework when it chooses to remove the process and all the static objects along with it. For this reason, if you have singleton classes populated with data and you exit your application and then later come back to the application, you may or may not find that the 'old' singleton instances are still around. For this reason, in my application (which uses a very large amount of global state) I've resorted to holding my singletons' actual instances in an extension of the .Application class, to (hopefully) better control their lifecycle.
With a Service you have a well-defined lifecycle with appropriate lifecycle callbacks (onCreate(), onDestroy(), etc.) just as you do with an Activity.
Yes, definitely use a Service. From the docs:
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user
While using a singleton might work for a while, your application would be prone to being killed by the operating system when it goes into the background unless you have a Service. If you're more comfortable with the singleton pattern, you could implement it in a singleton and then just tie it to a Service simply to maintain its lifecycle, but that seems more of a mess than it's worth. Note that you shouldn't do network operations on the UI thread and by default a Service runs on the UI thread. You'll need to spin up another thread to do your work.
I don't see anything in your post that demands a BroadcastReceiver, though perhaps there may be some network related broadcast intents that might be useful like android.net.ConnectivityManager.CONNECTIVITY_ACTION.

How do I organize this Android app with network i/o and multiple activities?

To begin with, this is the first Android app I'm writing, and I have very little prior Java experience. So nothing is too simple -- I could easily be missing anything "obvious".
Here's the general design I'm dealing with:
A long-lived bidirectional network connection.
Requests should go out over the network when the user interacts with the UI.
The UI should be updated when the responses to said requests come back -- asynchronously.
The app will contain multiple activities.
These activities will be focused on particular areas of functionality available, all relying upon the same underlying network connection. So I want to set up this connection no matter which activity my app starts in, and have it survive across switching to another activity in my app, but I want to shut it down when switching away from my app completely.
I think I want threads. I've got something basic working, but not well because I don't think I have them organized properly. I also am, so far, unable to pass data between the UI and network thread, so I can't get requests in nor actions for responses out. So I'd appreciate any advice.
I think I want threads.
You don't have a choice on that front. You will need a thread that listens on your socket for incoming data. Android is no different than standard Java in that respect.
I also am, so far, unable to pass data between the UI and network thread, so I can't get requests in nor actions for responses out.
Well, your thread should be managed by a Service. The network connection supports multiple activities, so no one activity should own the thread.
You will then need to decide when the network connection should exist. Since activities come and go, you will need to decide if the network connection should only exist when one of your activities is in the foreground (in which case you would likely bind to the service with bindService() from each activity), or whether there is an explicit "start" and "stop" operation that the user must do, so the connection can live after all of your activities are gone (in which case you would likely use startService() instead of bindService()).
Once you know when and how you are starting/stopping the service, you can decide how that service will communicate its results back to the various activities. There are tons of options, some better than others depending on your use case. Registered listeners, Messenger, broadcast Intents, a ContentProvider, and so on are all candidates. Any of those can be used by a background thread and can arrange to get data to the foreground activity on the main application thread. The other activities would typically refresh their data during onResume(), since there usually is no point in proactively updating them when they are not on the screen or may have even been kicked out of RAM.
IOW, "advice" is several chapters in a book or two. :-)

Categories

Resources