правильный способ использования сокетов в приложении для Android - PullRequest
15 голосов
/ 25 марта 2011

Я занимаюсь разработкой этого приложения, и мне нужно в какой-то момент отправить данные (в основном, двойные и строковые) на сервер.Я буду использовать сокет TCP и DataOutput / InputStreams.Мне было интересно, что будет лучшим способом сделать это.Должен ли я иметь отдельный класс для обработки соединения с реализованными методами записи / чтения, или, может быть, просто определить сокеты / потоки и т. Д. В моем основном классе Activity в onCreate ()?Первый путь вообще возможен?Любые примеры будут оценены.

пс.Должен ли я использовать другой поток для обработки соединения?

edit.
Так что, если я правильно понял, это должно быть правильно:

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;
}

}

, и я бы использовал что-то вроде этогов моем классе деятельности:

ConnectionHandler conhandler = new ConnectionHandler();
    conhandler.execute();
    conhandler.writeToStream(lat , lon);

1 Ответ

16 голосов
/ 25 марта 2011

Поскольку сетевые подключения могут занимать время и приводить к тому, что приложение перестает отвечать на запросы, если оно выполняется в потоке пользовательского интерфейса, вы, вероятно, должны делать это в AsyncTask . Если ваш AsyncTask достаточно сложен, возможно, его стоит реализовать в своем собственном java-файле как обычный открытый класс.

Этот ответ даст вам основной скелет. AsyncTask упрощает взаимодействие с пользовательским интерфейсом в начале и в конце фоновой загрузки, если вам нужно показать некоторые индикаторы хода выполнения.

Thread имеет тенденцию быть худшим выбором, так как вы по-прежнему сталкиваетесь с проблемой взаимодействия с пользовательским интерфейсом, когда ваш поток завершает работу, а также гарантирует, что поток не продолжит свою работу после завершения вашей деятельности; AsyncTask также можно отменить, и вместо onPostExecute.

будет выполнен onCancelled.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...