I am planning to implement Socket.io in android by this library for a chat based application. As far as I understood the library seems to be pretty good. I want to know how to maintain a single socket connection throughout the app all the time? Here I have listed out ways to achieve, in which I need the best and stable way.
MainApplication Class extends Application
By this we have a good scope that the socket connection is maintained in the main thread( or application’s life cycle) and whenever the socket instance is needed from the activity we can get it easily. But it’s main thread which also the problem. It might block the main thread.
By this way we can bind the service with the activities and we can simply use it. Doing in separate thread is the way to achieve IO/Network calls. But cross processing transfer is more expensive than directly accessing in same process.
Maintaining connection in Singleton also makes sense. But we don’t know when the instance is killed by process, because it doesn’t work in activity life cycle.
If I makes sense please help me out. If not comment it out.
I have given the answer which is more suitable for me.
First of all, the Application’s
onCreate() is irrelevant in your use case because you can’t have a thread running in the background when it was first initiated in a non service code.
Also, I would recommend using Google Cloud Messaging instead of creating your own mechanism. It would be best for the device’s battery life and much less code for you to handle.
If you do want to implement that chat completely on your own,
Service is your only choice. You can also combine it with a singleton, but I wouldn’t recommend that approach. You can use broadcasts and
BroadcastReceiver for communicating between your
Activity, I think it is easier than a Bound Service since bounding to the service is asynchronous and it creates a lot of mess compared to simple broadcasting.
Service for Maintaining
As per Ofek Ron mentioned
BroadcaseReceiver is a better idea than
BoundService. Because its a tedious process to maintain communication. And I also recommend
pub/sub way of broadcasting, like
EventBus (I myself suggest Otto by Square, which is clean and brilliant api).
Pros of OTTO
1. Cleaner Api
2. You can subscribe and publish in/to any
3. Decoupling. (You have to couple as less as possible in your code).
And one more point is use
START_STICKY in the
onStartCommand() to start service after it is getting destroyed. See this reference.
MainApplication to start the service
It’s best practice to start the service in the
MainApplication that extends
Application. Because the application will be killed when there is a memory constraint or user forcefully closes the app from the stack. So
onStartCommand() will not be called frequently like if we have implemented in Activity.
Implementing online status
You can implement online status simply by implementing
Application.LifeCycleCallbacks in the
MainApplication class, which has most of the life cycle callbacks of activity and will be notified in the callback. By that you can implement
Online status simply without any boiler plate codes. (If anyone need help here let me know).
Uploading or downloading images or files.
Best practice is to implement by
IntentService because it’s running in the a separate thread. I promise which will give the best performance because it is handled by android itself, not like threads created by us.
You can combine first way and third way like:
Sockets in your
Application and declare them as
static. So you can maintain and access them every where in you application. Don’t forget to create separate
Threads to perform the network operations, you can use
ThreadPool to manage those
Thread. If you want to update your UI from those
Thread you can use
Message to communication with UI
Before you create your own implementation of a socket.io client, you should give this library a chance: https://github.com/socketio/socket.io-client-java
I use it in one of my projects to communicate with a node.js server which is working pretty fine. Actually, all of your suggestions are correct and mostly depend on what you want to achieve. However, one context is always available: the application context. Therefore you should keep a singleton instance in the
Application class and get it by
Online status of the user: here you should create a background service which is listening constantly for the users state. As there are not many information, this should be okay and should not drain the battery too much. Additionally you can send a flag if there are new information available and only if there is something new, you start another thread, which is receiving the new data. This keeps the data low.
Chat: the chat data is transfered only when the app is active. So, this should be done in an activity.
Both the service and the activity can access the singleton instance of the socket.io client from the application context. As long as you do not process any complex data on the main thread everything is fine. So, wrap your calls into separate thread and only start them when they are actually needed.