2012-01-28 1 views
0

私はインターネット経由でチャットメッセージを送信するためにこのAsyncTaskを使用しています。問題は、私がタスクを実行しても何も起きないことです。少なくともUIではそうではありません。私はonProgressUpdate()がまったく実行しないと思う。そのアイデアは、タスクが開始されると、メッセージがインターネット上で送信され、UIのEditTextが新しいテキストで更新されるということです。ここにクラス全体があります:AsyncTaskからUIを使用してデータを返すことができません。

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) {} 
    } 

} 

何が間違っていますか?

答えて

1

onProgressUpdateは、hereのようにdoInBackgroundから明示的に呼び出される必要があります。あなたの場合に使用する正しい方法ではありません。私はむしろ、テキストフィールドの設定はonPostExecuteで行われるはずです。理由は、newConverstionの値はリモート呼び出しの直後に決定され、完了するまでに時間がかかることがあります。 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(""); 
    } 

基本的に最も重要なことは、タスクの背景の中で最も時間のかかる電話をかけることです。あなたの場合、これはsendMessageです。それ以降は、postExecuteとpreExecuteであなたが望むすべての修正を行うことができます。私は、あなたのonProgressUpdateに対するあなたの意図が何であるかについてはあまりよく分かりません。私はちょうどそれをonPostExecuteを使って翻訳しました。フィールドを一時的に無効にする必要がある場合は、onPreExecuteで無効にしてonPostExecuteを有効にすることができます。

+0

あなたのメールアドレス: AsyncTasksはAsyncTasksを使用して作成されました。あなたは、あなたの恋人のために恋人を探していますか? Мерсиипоздрави。 – RegedUser00x

+0

@ RegedUser00x:私は捕まった、本当に私はブルガリア人です。私はまた私の言語を愛し、それを話すことを好むでしょう。しかし、これはコミュニティサイトであり、私たちの言語は特別ですが、SOの公用語には適していないことに同意する必要があります。あなたの投稿を翻訳する: 'こんにちは、どのような方法で配置するのか分かりますか? AsyncTaskクラスは、私のすべてのメソッドを本当に混乱させます。ところで、Androidでのネットワークプログラミングについて読んだことのある本を私に指摘することはできます。なぜなら、ほとんど何も見つけることができないからです。ありがとうございます。 –

1

をご自分で電話しないと、onProgressUpdate()は呼び出されません。 the 4 steps of AsyncTaskを参照してください。

Borisが指摘したとおりです。 sendMessage()doInBackground()に、UIはonPostExecute()に更新する必要があります。

+0

私は皆さんから助言を受けていますが、今は 'socket.send(packet);でNullPointerExceptionを取得しました。 – RegedUser00x

+1

Socket初期化を回避するtry catchを削除します。私はこれがあなたの問題が本当に何を隠していると思います - IOExcaption –

関連する問題