Volo Apps
Volo Apps

Reputation: 235

Socket.IO With Service Draining Battery Dramatically (Android)

Good day.

I have a question considering the most best practise for battery managment.

Beforehand please do not suggest nor GCM neither Firebase as i am not interested in them and i will tell the reason after.

So here is the scenario.

I have a social network deployed of my own.

I hardly believe that Viber,WhatsApp or Telegram is using any of Google Services like GCM or Firebase and plus i have used both of them and i am dramatically dissatisfied about the delays of them and about the pricing i am receiving so the best option for me was to keep all of the notifications under the hood of the Socket.IO.

So each step now:

• I have created an always-running service which is running on no matter what.

• The service has Socket.IO lib attached to it and the service keeps persistent connection to the server via Socket.IO.

• The service handles all of the Socket.IO logic which are the next : The full application notifications - Group Notifications, Friend Request, Message Notifications and all of them, all counts around of 10 types of notifications which can be inside my application.

• Everything was perfect unless i saw that my Samsung S7 Edge complaining about the usage of my application. I though it was one of the Samsung typicall complains but when i saw the battery usage i was shocked... My app used MORE BATTERY THAN THE ANDROID OS which was a big hit to me.

I will shortly show you the code of my service :

i am intializing the socket like this.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    initSocketFully();
    return START_STICKY;
}

  private void initSocketFully() {
    sharedHelper = new SharedHelper(this);
    currentUserId = sharedHelper.getUserId();
    destroySocket();
    try {
        mSocket = IO.socket(SOCKET_URL);
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    initSocket();

}

 private void initSocket() {
    mSocket.on(EVENT_CONNECT, onSocketConnected);
    mSocket.on(EVENT_CONNECT_ERROR, onSocketConnectionError);
    mSocket.on(EVENT_DISCONNECT, onSocketDisconnected);
    mSocket.on(EVENT_NEW_MESSAGE, onNewMessageReceived);
    mSocket.on(EVENT_STOPPED_TYPING, onUserStoppedTyping);
    mSocket.on(EVENT_TYPING, onUserTyping);
    mSocket.on(EVENT_MESSAGE_SENT, onMessageSent);
    mSocket.on(EVENT_CONNECT_TIMEOUT, onSocketTimeOut);
    mSocket.on(EVENT_ONLINE_STATUS, onOnlineStatusReceived);
    mSocket.on(EVENT_ON_GAME_CREATED, onMafiaGameCreated);
    mSocket.on(EVENT_ON_COMMENT_ADDED, onCommentAdded);
    mSocket.on(EVENT_ON_FRIEND_REQUEST_ACCEPTED, onFriendRequestAccepted);
    mSocket.on(EVENT_ON_FRIEND_REQUEST_DECLINED, onFriendRequestDeclined);
    mSocket.on(EVENT_ON_POST_LIKED, onPostLiked);
    mSocket.on(EVENT_ON_POST_MADE, onPostMade);
    mSocket.on(EVENT_ON_FRIEND_REQUESTED, onFriendRequested);

    mSocket.connect();
}

Destroying it on the callback of sevice's onDestroy like so :

 private void destroySocket() {
    if (mSocket != null) {
        mSocket.disconnect();
        mSocket.off(EVENT_CONNECT, onSocketConnected);
        mSocket.off(EVENT_ON_FRIEND_REQUEST_ACCEPTED, onFriendRequestAccepted);
        mSocket.off(EVENT_CONNECT_ERROR, onSocketConnectionError);
        mSocket.off(EVENT_ON_FRIEND_REQUEST_DECLINED, onFriendRequestDeclined);
        mSocket.off(EVENT_DISCONNECT, onSocketDisconnected);
        mSocket.off(EVENT_NEW_MESSAGE, onNewMessageReceived);
        mSocket.off(EVENT_STOPPED_TYPING, onUserStoppedTyping);
        mSocket.off(EVENT_ON_GAME_CREATED, onMafiaGameCreated);
        mSocket.off(EVENT_TYPING, onUserTyping);
        mSocket.off(EVENT_MESSAGE_SENT, onMessageSent);
        mSocket.off(EVENT_CONNECT_TIMEOUT, onSocketTimeOut);
        mSocket.off(EVENT_ONLINE_STATUS, onOnlineStatusReceived);
        mSocket.off(EVENT_ON_COMMENT_ADDED, onCommentAdded);
        mSocket.off(EVENT_ON_POST_LIKED, onPostLiked);
        mSocket.off(EVENT_ON_POST_MADE, onPostMade);
        mSocket.off(EVENT_ON_FRIEND_REQUESTED, onFriendRequested);
    }
}

Important notice that i am starting this service every 10 minutes over and over which is the guarantee that if system kills the service process, yet it will be again started and no delays for the user will be.

My question is the next :

How to optimize all of these logic not to drain the battery of phone more then Android OS as it is ridicilous to drain the user's device battery in that way, but i believe there must be some good practise where i MUST NOT use firebase nor GCM and i MUST NOT close the Socket and open it very late and let user feel huge delays as it will distract user from my application...

So any ideas or a code improvement?

Upvotes: 4

Views: 2209

Answers (2)

Deepanshu Kacher
Deepanshu Kacher

Reputation: 11

You could use MQTT stands for MQ Telemetry Transport It is very light weight and very power efficient protocol that is even much efficient then http protocol, but max media size is approx 260MB.

It is made for IoT devices, machine-to-machine (M2M)/”Internet of Things” connectivity

link :- https://mqtt.org/

Upvotes: 0

Stephane Piedjou
Stephane Piedjou

Reputation: 149

You issue is that your app never sleeps as the socket is always on. It is true you said you are not interested in GCM (FCM) but the best solution might be to use both SocketIO and FCM together. You use SocketIO when your app is in foreground as message delivery is quicker as you explained. When you app is in background you kill your socket and use FCM to deliver notifications as it is more optimise for battery life.

Upvotes: 4

Related Questions