Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

proper way of using sockets in android app

I am developing this app and i need at some point to send data (doubles and strings mostly) to a server. I will be using TCP socket and DataOutput/InputStreams. I was wondering what would be the best way to do this. Should i have a seperate class to handle the connection with write/read methods implemented or maybe just define Sockets/Streams etc in my main Activity class in onCreate()? Is the first way even possible? Any examples would be appreciated.

ps. Should i use a different Thread to handle the connection?

edit.
So if i got it right, this should be correct:

public class ConnectionHandler extends AsyncTask<Void, Void, Void>{

public static String serverip = "192.168.1.100";
public static int serverport = 7777;
Socket s;
public DataInputStream dis;
public DataOutputStream dos;
public int message;

@Override
protected Void doInBackground(Void... params) {

    try {
        Log.i("AsyncTank", "doInBackgoung: Creating Socket");
        s = new Socket(serverip, serverport);
    } catch (Exception e) {
        Log.i("AsyncTank", "doInBackgoung: Cannot create Socket");
    }
    if (s.isConnected()) {
        try {
            dis = (DataInputStream) s.getInputStream();
            dos = (DataOutputStream) s.getOutputStream();
            Log.i("AsyncTank", "doInBackgoung: Socket created, Streams assigned");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket not connected");
            e.printStackTrace();
        }
    } else {
        Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket is closed");
    }
    return null;
}

public void writeToStream(double lat, double lon) {
    try {
        if (s.isConnected()){
            Log.i("AsynkTask", "writeToStream : Writing lat, lon");
            dos.writeDouble(lat);
            dos.writeDouble(lon);
        } else {
            Log.i("AsynkTask", "writeToStream : Cannot write to stream, Socket is closed");
        }
    } catch (Exception e) {
        Log.i("AsynkTask", "writeToStream : Writing failed");
    }
}

public int readFromStream() {
    try {
        if (s.isConnected()) {
            Log.i("AsynkTask", "readFromStream : Reading message");
            message = dis.readInt();
        } else {
            Log.i("AsynkTask", "readFromStream : Cannot Read, Socket is closed");
        }
    } catch (Exception e) {
        Log.i("AsynkTask", "readFromStream : Writing failed");
    }
    return message;
}

}

and i would use something like this in my Activity class:

ConnectionHandler conhandler = new ConnectionHandler();
    conhandler.execute();
    conhandler.writeToStream(lat , lon);
like image 383
kotsosh Avatar asked Mar 24 '11 21:03

kotsosh


1 Answers

Since network connections can take up time and make your app unresponsive if done on the UI thread, you should probably do them in an AsyncTask. If your AsyncTask is sufficiently complex it could be worth implementing in its own java file as a proper public class.

This answer would give you the basic skeleton. AsyncTask makes it easy to interact with the UI at the beginning and the end of your background loading, if you needed to show some progress indication.

Thread tends to be a worse choice as you are still left with the problem of UI interaction when your thread completes as well as making sure that the thread doesn't continue its work after your activity finishes; an AsyncTask can be also be cancelled and then onCancelled will get executed instead of onPostExecute.

like image 154
Matthew Willis Avatar answered Oct 18 '22 02:10

Matthew Willis