TCP socket in Android

350 Views Asked by At

My problem is I have implemented a TCP socket client in android which sends continuously "Hello" messages to the server to maintain a client-server connection and receives messages from the server.

In Android, I have initialized a boolean variable that is controlling the thread if my app is in the background I make the "AppConfig.finished" variable true inactivity on pause and on stop method to stop the socket thread and make it false when in on resume state.

But my app is consuming high CPU usage which is making my app slow, I have checked it in android's profiler. Please help me to optimize it.

The code is given below.

public class MyTcp extends Thread{


private BufferedInputStream inputStream;
private BufferedOutputStream outputStream;
private Socket MySock;
private static SocketStatus SS;
private int ConnectAttemptCount = 0;
private CheckConnectionStatus CheckStatus = null;
public boolean FirstAttempt = true;
public boolean Continue = true;
private boolean isDirectChecked = false;
String tempData = "";
private final ArrayBlockingQueue<String> Queue = new ArrayBlockingQueue<>(100);

public MyTcp(SocketStatus SS) {
    MyTcp.SS = SS;
    MyTcp.SS.isConnected = false;

    setDaemon(true);
    Thread t = new Thread(new DequeueMessageThread());
    t.setName(SS.SocketName + " DequeqeMessageThread");
    t.start();
    setName(SS.SocketName);

}


public void Dispose() {
    try {

        Continue = false;
        SS.isConnected = false;
        if(inputStream != null) {
            inputStream.close();
        }

        if(outputStream !=null) {
            outputStream.close();
        }
        if(MySock != null) {
            MySock.close();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void run() {

    if(!Logs.isFinished) {
        try {

            while (Continue) {
                if (SS.isConnected) {
                    String fromServer = ReceiveMsg();
                    if (fromServer.compareTo("") != 0) {
                        Queue.put(fromServer);
                    }
                    ConnectAttemptCount = 0;

                } else {
                    if (ConnectAttemptCount < SS.ConnectAttempt) {
                        println("run>>" + "Connection Attempt" + ConnectAttemptCount);
                        ConnectAttemptCount++;
                        Connect();

                    } else {

                        println("run>>" + "Unable To Connect to server");
                        break;
                    }
                }
            }

        } catch (Exception e) {
            println("run Exception>>" + e);
        }
    }

}

public void Connect() {
    if(!Logs.isFinished) {
        try {
            if (SS.isDoQueueEmptyOnConnect) {
                Queue.clear();
                tempData = "";
            }
            if (FirstAttempt) {
                FirstAttempt = false;
            } else {


                Utilities.println("Trying to connect with " + SS.ServerIP + " on Port " + SS.Port);
                _fireStatsEvent(Status.Reconnecting, "Trying to connect with " + SS.ServerIP);
                Random generator = new Random();
                long wait = (long) generator.nextInt(3000) + 500;
                Thread.sleep(wait);
            }


            MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {

                public Object run() {


                    try {
                        // Start Secure Code
                        return (new Socket(SS.ServerIP, SS.Port));
                        // End Secure Code
                    } catch (Exception e) {
                        println("Connect Exception>>" + e.toString());
                    }


                    return null;
                }
            });


            if (MySock != null) {


                SS.isConnected = true;
                SocketStatus.MySock = MySock;
                inputStream = new BufferedInputStream(MySock.getInputStream());
                outputStream = new BufferedOutputStream(MySock.getOutputStream());

                Utilities.println("Connection established with " + SS.ServerIP + " on Port " + SS.Port);

                if (SocketStatus.EnablePingPong) {
                    if (CheckStatus != null) {
                        CheckStatus.Dispose();
                    }
                    SS.LastMsgTime = new Date();
                    CheckStatus = new CheckConnectionStatus(SS, this);
                    CheckStatus.setName(SS.SocketName + "Connection Status Thread");
                    CheckStatus.start();
                }


            }

        } catch (Exception e) {
            println("Connect>>" + e);
        }

        int ConnectToIPCount = 0;
        if (!SS.isConnected) {

            while (!SS.isConnected && ConnectToIPCount < SS.ServerIPList.size()) {
                final String IP_ = SS.ServerIPList.get(ConnectToIPCount).toString();
                final int Port_ = SS.Port;
                println("Connect>>" + "Trying to connect with " + IP_ + " on Port " + Port_);


                ConnectToIPCount++;

                try {
                    Thread.sleep(5000);
                    MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {

                        public Object run() {
                            try {
                                // Start Secure Code

                                if (!isDirectChecked) {
                                    isDirectChecked = true;
                                    Socket tempSock = new Socket(Proxy.NO_PROXY);
                                    tempSock.connect(new InetSocketAddress(IP_, Port_));
                                    return tempSock;

                                } else {
                                    return (new Socket(IP_, Port_));

                                }
                                // End Secure Code
                            } catch (Exception e) {
                                println("Connect Exception>>" + e.toString());
                            }
                            return null;
                        }
                    });
                    if (MySock != null) {

                        SocketStatus.MySock = MySock;
                        SS.isConnected = true;
                        inputStream = new BufferedInputStream(MySock.getInputStream());
                        outputStream = new BufferedOutputStream(MySock.getOutputStream());
                        Utilities.println("Connection established with " + IP_ + " on port " + Port_);

                        if (SocketStatus.EnablePingPong) {
                            if (CheckStatus != null) {
                                CheckStatus.Dispose();
                            }
                            SS.LastMsgTime = new Date();
                            CheckStatus = new CheckConnectionStatus(SS, this);
                            CheckStatus.setName(SS.SocketName + "Connection Status Thread");
                            CheckStatus.start();

                        }
                    }
                } catch (UnknownHostException e) {
                    println("Connect UnknownHostException>>" + e.toString());
                } catch (IOException e) {
                    println("Connect IOException>>" + e.toString());
                } catch (Exception e) {
                    println("Connect Exception>>" + e.toString());
                }
            }

        }
    }

}

public void SendMsg(String sendMsg) {

    if(!Logs.isFinished) {
        try {

            println("SendMsg>>" + sendMsg);

            if (MySock != null && MySock.isConnected()) {
                try {
                    byte[] b = null;
                    b = sendMsg.getBytes();
                    outputStream.write(b, 0, b.length);
                    outputStream.flush();
                } catch (SocketException | SocketTimeoutException e) {
                    if (MySock != null) {
                        MySock.close();
                    }
                    SS.isConnected = false;


                } catch (Exception e) {
                    println("SendMsg Exception>>" + e.toString());

                }

            }


        } catch (Exception e) {
            Log.d("TCP Client SendMsg >>", "Unable To Connect to server");
        }

    }
}


public String ReceiveMsg() {


    String recvMsg = "";

    if(!Logs.isFinished) {

        try {

            byte[] b = new byte[8092 * 6];
            int recvsz = 0;


            if (MySock != null && MySock.isConnected()) {
                recvsz = inputStream.read(b, 0, b.length);
                if (recvsz > 0) {
                    try {
                        byte[] b2 = new byte[recvsz];
                        System.arraycopy(b, 0, b2, 0, b2.length);

                        recvMsg = (new String(b2));
                        if (recvMsg.length() > 0) {
                            SS.LastMsgTime = new Date();
                        }
                    } catch (Exception e) {
                        println("ReceiveMsg Exception>>" + e.toString());
                    }
                }
            }

        } catch (Exception e) {
            if (SS.isConnected) {

                Utilities.handleException(e);

            }
            SS.isConnected = false;
            println("ReceiveMsg Exception>>>" + e.toString());
            Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + e.toString() + "'");

        }
    }

    return recvMsg;
}

public void println(String msg) {
    if (SS.Debug) {
        String strDateFormat1 = "HH:mm:ss";
        SimpleDateFormat sdf1 = new SimpleDateFormat(strDateFormat1);
         Utilities.println(SS.SocketName + " (" + sdf1.format(new Date()) + ") " + msg);
    }
}

private final List<MessageRecieveListner> _listeners = new ArrayList<>();
private final List<MessageRecieveListner> _listenersStrength = new ArrayList<>();

public synchronized void addListener(MessageRecieveListner l) {
   _listeners.add(l);
   _listenersStrength.add(l);
}




private synchronized void _fireMessageEvent(String msg) {
    MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, msg);
    for (MessageRecieveListner listener : _listeners) {
        listener.MessageRecieved(MsgEvent);

    }
}


public synchronized void _fireStatsEvent(Status status, String msg) {
    MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, status, msg);

    for (MessageRecieveListner listener : _listeners) {
        listener.ConnectionStatus(MsgEvent);
    }
}

private class DequeueMessageThread implements Runnable {

    public DequeueMessageThread() {
    }

    @Override
    public void run() {
        if(!Logs.isFinished) {
            while (Continue) {
                if (!Queue.isEmpty()) {
                    try {
                        String data = Queue.take().trim();
                        if (SS.MessageParser.length() > 0) {
                            if (data.lastIndexOf(SS.MessageParser) == data.length() - 1) {
                                _fireMessageEvent(tempData + data);
                                tempData = "";
                            } else {
                                if (data.indexOf(SS.MessageParser) > 0) {
                                    String particalCompleteData = tempData + data.substring(0, data.lastIndexOf(SS.MessageParser));
                                    tempData = data.substring(data.lastIndexOf(SS.MessageParser) + 1);
                                    _fireMessageEvent(particalCompleteData);
                                    Utilities.println("incomplete data");
                                }
                            }
                        } else {
                            _fireMessageEvent(data);
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        Continue = false;
                    }
                }

            }
        }
    }
}
0

There are 0 best solutions below