проблема синхронизации потоков при использовании AsyncTask, Android - PullRequest
1 голос
/ 28 марта 2011

Я делаю и приложение для отправки данных с помощью сокетов с устройства Android на сервер и обратно. Я использую класс AsyncTask для обработки соединения. Моя проблема в том, что в какой-то момент в моем основном классе Activity я должен читать из входного потока, например.

    conhandler = new ConnectionHandler();
    conhandler.execute();
    Log.i("AppOne", "Reading from stream");
    message = conhandler.readFromStream();

и получается, что этот фрагмент кода выполняется до того, как мой класс ConnectionHandler установил соединение с сокетом. Есть ли способы решить эту проблему? Вот код моего класса ConnectionHandler:

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 = null;
public DataOutputStream dos = null;
public int message;



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

    try {
        Log.i("AsyncTank", "doInBackgoung: Creating Socket");
        s = new Socket("192.168.1.100", 7777);
    } catch (Exception e) {
        Log.i("AsyncTank", "doInBackgoung: Cannot create Socket");
    }
    Log.i("AsyncTank", "doInBackgoung: Socket created");
    if (s.isConnected()) {
        try {
            Log.i("AsyncTank", "doInBackgoung: inside input try");
            dis = new DataInputStream(s.getInputStream());
            Log.i("AsyncTank", "doInBackgoung: InputStream assigned");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket not connected");
            e.printStackTrace();
        }
        try {
            Log.i("AsyncTank", "doInBackgoung: inside output try");
            dos = new DataOutputStream(s.getOutputStream());
            Log.i("AsyncTank", "doInBackgoung: OutputStream 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 {
            Log.i("AsynkTask", "writeToStream : Writing lat");
            dos.writeDouble(lat);
            dos.flush();
        } catch (Exception e) {
        Log.i("AsynkTask", "writeToStream : Writing failed");
    }
    try {
            Log.i("AsynkTask", "writeToStream : Writing lon");
            dos.writeDouble(lon);
            dos.flush();
        } 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 : Reading failed");
    }
    return message;
}

}

1 Ответ

2 голосов
/ 28 марта 2011

Да, вам нужно выполнить все сетевые операции в потоке ASyncTask.Вы также можете сделать что-то после завершения задачи, переопределив метод onPostExecute().Там все работает в потоке пользовательского интерфейса, поэтому вы можете манипулировать текстовыми представлениями, макетами и т. Д.

Пример того, как вы можете использовать асинхронную задачу, чтобы открыть сокет и записать в него двойное число:

public class ASyncExample extends Activity {

    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // set stuff up
        super.onCreate(savedInstanceState);
    }

    private class WriteToServer extends AsyncTask<Double, Void, Void> {

        private final String serverip = "192.168.1.100";
        private final int serverport = 7777;
        Socket s;
        private DataOutputStream dos = null;

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

            try {

                // open the stream
                s = new Socket("192.168.1.100", 7777);
                dos = new DataOutputStream(s.getOutputStream());

                // write the passed double to the stream
                dos.writeDouble(params[0]);
                dos.flush();

            } catch (Exception e) {
                Log.i("AsyncTank", "something's gone wrong");
            }

            return null;
        }
    }
}
...