Не удается отправить данные обратно с помощью пользовательского интерфейса из AsyncTask - PullRequest
0 голосов
/ 28 января 2012

У меня есть AsyncTask, который я использую для отправки сообщения чата через Интернет.Проблема в том, что когда я выполняю задачу, ничего не происходит - по крайней мере, не в пользовательском интерфейсе.Я подозреваю, что onProgressUpdate() не выполняется вообще.Идея состоит в том, что, когда задача запускается, сообщение будет отправлено через Интернет, и текст EditText в пользовательском интерфейсе будет обновлен новым текстом.Вот весь класс:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

import android.os.AsyncTask;
import android.widget.EditText;

public class Messager extends AsyncTask<SocketAndEditText, Void, Void> {

    private MulticastSocket socket;
    private EditText host;
    private EditText port;
    private EditText sendMessage;
    private EditText messageBoard;
    private InetAddress serverAddress;
    private int pt;
    private String newConverstion;
    private String message;

    @Override
    protected Void doInBackground(SocketAndEditText... soEd) {
        // get the text that they contain and add the new messages to the old ones
        //host = soEd[0].getHost();
        //port = soEd[0].getPort();
        messageBoard = soEd[0].getMessageBoard();
        sendMessage = soEd[0].getSendMessage();

        message = sendMessage.getText().toString();
        String conversation = messageBoard.getText().toString();

        newConverstion = conversation.concat("\n[You] ").concat(message);

        return null;
    }

    protected void onProgressUpdate(Integer... progress) {
        // make the messages text view editable
        messageBoard.setFocusable(true);
        messageBoard.setText(newConverstion);   // add the new message to the text view
        messageBoard.setFocusable(false);   // make the messages text view not editable

        // erase the text on the second text view that has just been sent
        sendMessage.setText("");

        sendMessage(message);
    }

    public void sendMessage(String message) {
        // convert the host name to InetAddress
        try {
            serverAddress = InetAddress.getByName("localhost");
        } catch (Exception e) {}
            pt = 4456;

        // create socket and start communicating
        try {
            socket = new MulticastSocket(pt);
            socket.joinGroup(serverAddress);
        } catch (IOException e) {}

        // Send message to server

        // convert message to bytes array
        byte[] data = (message).getBytes();

        // create and send a datagram
        DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, pt);

        try {
            socket.send(packet);
        } catch (IOException e) {}
    }

}

Что может быть не так?

Ответы [ 2 ]

1 голос
/ 28 января 2012

onProgressUpdate () не будет вызываться, если вы сами не вызовете publishProgress () . См. 4 шага AsyncTask .

Как отметил Борис. Вы должны позвонить sendMessage() в doInBackground() и обновить пользовательский интерфейс в onPostExecute().

1 голос
/ 28 января 2012

onProgressUpdate должен вызываться явно из doInBackground, как видно здесь .Это не правильный метод для использования в вашем случае.Я предпочел бы ожидать, что настройка текстового поля должна быть сделана в onPostExecute .Причина в том, что значение newConverstion определяется сразу после удаленного вызова, и для его завершения может потребоваться некоторое время.Если вы делаете это до того, как асинктическая задача завершит выполнение, вы рискуете NPE.

Редактировать Добавление некоторого кода:

    public class Messager extends AsyncTask<SocketAndEditText, Void, Void> {

   //skipping some field declaration

    @Override
    protected Void doInBackground(SocketAndEditText... soEd) {
        // get the text that they contain and add the new messages to the old ones
        //host = soEd[0].getHost();
        //port = soEd[0].getPort();
        messageBoard = soEd[0].getMessageBoard();
        sendMessage = soEd[0].getSendMessage();

        message = sendMessage.getText().toString();
        sendMessage(message); //NOTE: added the remote call in the background method. This is the only thing that really SHOULD be done in background. 

        String conversation = messageBoard.getText().toString();

        newConverstion = conversation.concat("\n[You] ").concat(message);

        return null;
    }

    protected void onPostExecute(Void result) {
        // make the messages text view editable
        messageBoard.setFocusable(true);
        messageBoard.setText(newConverstion);   // add the new message to the text view
        messageBoard.setFocusable(false);   // make the messages text view not editable

        // erase the text on the second text view that has just been sent
        sendMessage.setText("");
     }

В основном, самое важное - это разместить наиболеетрудоемкие звонки в фоновом режиме задачи.В вашем случае это sendMessage.С этого момента вы можете делать любые исправления, которые пожелаете, в postExecute и preExecute.Я не совсем уверен, каково было ваше намерение для onProgressUpdate.Я только что перевел это на использование onPostExecute.Если вам нужно временно отключить это поле, вы можете отключить его в onPreExecute и включить его на PostExecute.

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