I am writing an Android app, finally (yay me) and for this app I need persistant, but user closeable, network sockets (yes, more than one). I decided to try my hand at writing my own version of an IRC Client.
My design issue however, is I’m not sure how to run the Socket connectivity itself. If I put the sockets at the Activity level, they keeps getting closed shortly after the Activity becomes non-visible (also a problem that needs solving…but I think i figured that one out)…but if I run a “connectivity service”, I need to find out if I can have multiple instances of it running (the service, that is…one per server/socket). Either that or a I need a way to Thread the sockets themselves and have multiple threads running that I can still communicate with directly (ID system of some sort).
Thus the question: Is it a ‘better’, or at least more “proper” design pattern, to put the Socket and networking in a service, and have the Activities consume said service…or should I tie the sockets directly to some Threaded Process owned by the UI Activity and not bother with the service implementation at all? I do know better than to put the networking directly on the UI thread, but that’s as far as I’ve managed to get.
1
The answer is Service
+ Thread
.
Don’t put the socket
in an Activity
. The activity
is for UI. It gets recreated when the user rotates the phone. You can run into problems when the user receives a phone call.
Put your sockets in a Service
. Your activity/activities can bind to the Service
and use it’s methods. Or you can use a Messenger to communicate between an Activity
and the Service
.
Services
on Android run in the UI thread so in the Service
you’ll need your own thread for the socket communication.
Just a suggestion (something I haven’t yet tried w/Android, but should work).
Try putting a WebView in your main activity (so it won’t die when you switch child activities) which includes a full DOM document and a child iframe element. Set the iframe’s src attribute to a comet service you define, with a keep-alive header. Push the messages using comet. Works like a charm in chrome. If your back end doesn’t support comet, you can set it up manually.