AsyncTask не возвращает результаты сразу

1

Прочитав несколько сообщений и прочитав на странице разработчиков об ASYNCTASK, я придумал следующий код и назначил его кнопке:

private class TalkToServerTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        String response = "";
        try {
            InetAddress serverAddr = InetAddress.getByName(params[0]);
            Socket s = new Socket(serverAddr, Integer.valueOf(params[1]));

            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(s.getOutputStream())), true);

            // WHERE YOU ISSUE THE COMMANDS

            out.println(params[2]);
            // BufferedReader input = new BufferedReader(
            // new InputStreamReader(s.getInputStream()));

            DataInputStream dataInputStream = null;
            dataInputStream = new DataInputStream(s.getInputStream());
            st = dataInputStream.readLine().toString();
            // String st = s.readLine();
            // st = input.readLine();
            // read line(s)

            s.close();
            return st;

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        serverresponse = result;
    }

}

Идея заключается в том, что при нажатии кнопки ASyncTask отправляет слово "getDomains" в консольное приложение, запущенное на моем сервере, сервер действует на него и отправляет обратно строку со списком доменов, созданных на сервере электронной почты.

Я проверил, что сервер получает команду "getdomains", и он, в свою очередь, отвечает на строку с ограничениями по каналам. Однако проблема заключается в том, что я установил Toast для вывода результатов транзакции сокета, и тост ничего не показывает. Если я снова нажму кнопку, тост отобразит список доменов. Для меня кажется, что сокет сначала возвращает пустой

Вот код кнопки:

case R.id.btnDomains:
            SharedPreferences sp = PreferenceManager
                    .getDefaultSharedPreferences(this);
            IpAddress = sp.getString("ipaddress", "0.0.0.0");
            Serverport = sp.getString("tcpport", "12345");
            buttonpressed = "domains";
            // TalkToServerTask task = new TalkToServerTask();
            new TalkToServerTask().execute(IpAddress, Serverport, "getDomains");

            Intent buttonActivity = new Intent(MainActivity.this, Rules.class);
            buttonActivity.putExtra(MainActivity.DOMAINLIST, serverresponse);

            Toast.makeText(getApplicationContext(), serverresponse,
                    Toast.LENGTH_SHORT).show();

переменная "serverresponse" - это то, что сначала показывает пустой, но затем показывает список серверов.

  • 1
    AsyncTask должен работать не сразу, он должен работать в отдельном потоке. вы должны изменить пользовательский интерфейс с onPostExecute
  • 0
    для таких целей рекомендуется использовать веб-сервис, а не сокеты ...
Теги:
sockets
android-asynctask

3 ответа

3
Лучший ответ

Как отметил Топош, AsyncTask работает над отдельным потоком.

Поэтому поток выполняется и еще не получил результата, когда вы в первый раз нажимаете кнопку.

Вы должны показать данные в методе onPostExecute. Также вы должны передать контекст вашему AsyncTask.

public TalkToServerTask(Context context)  {
    this.context = context;
}

@Override
protected void onPostExecute(String result) {
    Intent buttonActivity = new Intent(context, Rules.class);
    buttonActivity.putExtra(MainActivity.DOMAINLIST, result);

    Toast.makeText(context.getApplicationContext(), result, Toast.LENGTH_SHORT).show();
}
  • 0
    Спасибо за ответ!
0

Вам просто нужно немного изменить свой код,

Вам нужно переместить эти 3 строки,

Intent buttonActivity = new Intent(MainActivity.this, Rules.class); 
buttonActivity.putExtra(MainActivity.DOMAINLIST, serverresponse); 
// and also the line to startActivity() as well.
Toast.makeText(getApplicationContext(), serverresponse, 
                    Toast.LENGTH_SHORT).show(); 

от вашего Switch..case к onPostExecute из AsyncTask где вы написали serverresponse = result

Это потому, что AsyncTask работает в другом потоке, а вы выполнили в Swtich... случай не так, что следующая строка кода не будет выполняться до завершения AsyncTask, поэтому весь зависимый код должен быть записан в onPostExecute задачи,

0

AsynTask запускается в отдельном потоке из потока пользовательского интерфейса. Таким образом, есть 2 потока, выполняющихся параллельно. Пока вы пытаетесь отобразить список в тосте в основном потоке пользовательского интерфейса, AsynTask все еще готовится к извлечению списка или, возможно, созданию сокетов в своем потоке. Следовательно, данные списка все еще пусты.

postexecute метод Asynctask запускается в основном потоке пользовательского интерфейса, поэтому его безопасно и правильно обновлять пользовательский интерфейс.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню