Java Can';t使用UI从异步任务发送数据

Java Can';t使用UI从异步任务发送数据,java,android,multithreading,android-asynctask,Java,Android,Multithreading,Android Asynctask,我有一个异步任务,我用它通过互联网发送聊天信息。问题是,当我执行任务时,什么都没有发生——至少在UI上没有。我怀疑onProgressUpdate()根本没有执行。其思想是,当任务启动时,将通过internet发送一条消息,并使用新文本更新UI上的EditText。下面是全班同学: import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.Mul

我有一个异步任务,我用它通过互联网发送聊天信息。问题是,当我执行任务时,什么都没有发生——至少在UI上没有。我怀疑
onProgressUpdate()
根本没有执行。其思想是,当任务启动时,将通过internet发送一条消息,并使用新文本更新UI上的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) {}
    }

}
import java.io.IOException;
导入java.net.DatagramPacket;
导入java.net.InetAddress;
导入java.net.MulticastSocket;
导入android.os.AsyncTask;
导入android.widget.EditText;
公共类消息器扩展异步任务{
专用多播套接字;
私有文本主机;
专用文本端口;
私人编辑文本发送消息;
私人编辑文本留言板;
私有地址服务器地址;
私人int pt;
私有字符串会话;
私有字符串消息;
@凌驾
受保护的Void doInBackground(SocketAndEditText…soEd){
//获取它们包含的文本,并将新消息添加到旧消息中
//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();
NewConversation=conversation.concat(“\n[您]”).concat(消息);
返回null;
}
受保护的void onProgressUpdate(整数…进度){
//使消息文本视图可编辑
messageBoard.setFocusable(true);
messageBoard.setText(newconversation);//将新消息添加到文本视图
messageBoard.setFocusable(false);//使消息文本视图不可编辑
//擦除刚刚发送的第二个文本视图上的文本
sendMessage.setText(“”);
发送消息(message);
}
公共无效发送消息(字符串消息){
//将主机名转换为InetAddress
试一试{
serverAddress=InetAddress.getByName(“本地主机”);
}捕获(例外e){}
pt=4456;
//创建套接字并开始通信
试一试{
插座=新的多播插座(pt);
socket.joinGroup(服务器地址);
}捕获(IOE){}
//向服务器发送消息
//将消息转换为字节数组
字节[]数据=(消息).getBytes();
//创建并发送数据报
DatagramPacket packet=新的DatagramPacket(data,data.length,serverAddress,pt);
试一试{
socket.send(包);
}捕获(IOE){}
}
}

有什么问题吗?

onProgressUpdate
应该从doInBackground中显式调用,如图所示。在您的案例中,这不是正确的方法。我希望文本字段的设置应该在中完成。原因是,
newconversation
的值是在远程调用之后确定的,可能需要一段时间才能完成。如果在asynctask完成执行之前执行此操作,则有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("");
     }
公共类消息器扩展异步任务{
//跳过某些字段声明
@凌驾
受保护的Void doInBackground(SocketAndEditText…soEd){
//获取它们包含的文本,并将新消息添加到旧消息中
//host=soEd[0]。getHost();
//port=soEd[0]。getPort();
messageBoard=soEd[0]。getMessageBoard();
sendMessage=soEd[0]。getSendMessage();
message=sendMessage.getText().toString();
sendMessage(message);//注意:在后台方法中添加了远程调用。这是唯一真正应该在后台执行的操作。
String conversation=messageBoard.getText().toString();
NewConversation=conversation.concat(“\n[您]”).concat(消息);
返回null;
}
受保护的void onPostExecute(void结果){
//使消息文本视图可编辑
messageBoard.setFocusable(true);
messageBoard.setText(newconversation);//将新消息添加到文本视图
messageBoard.setFocusable(false);//使消息文本视图不可编辑
//擦除刚刚发送的第二个文本视图上的文本
sendMessage.setText(“”);
}
基本上,最重要的是将最耗时的调用放在任务的后台。在您的情况下,这是sendMessage。从那时起,您可以在postExecute和preExecute中执行任何您希望的修复。我不太确定您对onProgressUpdate的意图是什么。我只是将其转换为使用onPostExe可爱。如果需要临时禁用该字段,可以在onPreExecute中禁用它,并在PostExecute中启用它。

如果不调用自己,则不会调用该字段。请参阅


正如Boris指出的,您应该在
doInBackground()
中调用
sendMessage()
,并在
onPostExecute()中更新UI“代码<<

p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>p>>波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波波切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切切雅各布雷杰杜塞尔00X:我被抓住了,真的我是保加利亚人。我也喜欢我的语言,更喜欢用它说话。不过,这是社区网站,你应该同意我们的语言,尽管很特别,但不是适用于SO的官方语言。翻译您的帖子:
Hi,您知道在哪个方法中放置什么吗?AsyncTask类reall