0

我有一個應用程序連接到遠程聊天服務器,然後用戶可以聊天。我有一個表單,用戶輸入主機名和端口,然後用戶可以看到所有消息並鍵入新消息。Android AsyncTask和網絡mayham

對於網絡,似乎我沒有其他選擇,只能使用AsyncTask。但有些東西我不知道該怎麼做。當onCreate()被調用時,我會在UI中啓動網絡,這不是問題。但是當我必須連接網絡和接口時,它變得一團糟。我創建了兩個異步任務 - 一個用於發送,一個用於接收,但它不適用於我。這是我第一次開始SenderTask這是應該開始通信通過調用接收器的任務,如果一個按鈕將被按下發送一條新信息的代碼:

public class Second extends Activity { 

    private SenderTask snd; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.second); 

     // ... 

     final Button sendButton = (Button) findViewById(R.id.button2); 

     snd = new SenderTask(); 
     snd.doInBackground(editTexts); 

     sendButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // when the button is clicked the next screen is loaded 
       snd.onProgressUpdate(true); 
      } 
     }); 

    } // end of onCreate 

} 

然後這裏是SenderTask類:

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 SenderTask extends AsyncTask<EditText, Boolean, Void> { 

    MulticastSocket so; 
    InetAddress serverAddress; 
    int port; 
    EditText eText1; 
    EditText eText2; 
    EditText eText3; 
    EditText messageBoard; 

    @Override 
    protected Void doInBackground(EditText... eTexts) { 
     eText1 = eTexts[0]; 
     eText2 = eTexts[1]; 
     eText3 = eTexts[2]; 
     messageBoard = eTexts[3]; 
     setUp(); 

     return null; 
    } 

    private void setUp() { 
     // convert the host name to InetAddress 
     try { 
      //serverAddress = InetAddress.getByName(eText1.getText().toString()); 
      serverAddress = InetAddress.getByName("my server name is here"); 
     } catch (Exception e) {} 

     //convert the port to an int 
     //port = Integer.parseInt(eText2.getText().toString()); 
     port = 4456; 

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


     // Start listening should be here 
     ReceiverTask rec = new ReceiverTask(); 
     rec.doInBackground(messageBoard); 
     rec.onProgressUpdate(so); 
    } 

    private void sendMessage() { 

     // get the text that they contain and add the new messages to the old ones 
     String message = eText3.getText().toString(); 
     String conversation = messageBoard.getText().toString(); 
     String newConverstion = conversation.concat("\n[You] ").concat(message); 

     // 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 
     eText3.setText(""); 

     // 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, port); 

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


    } // end of sendMessage 

    protected void onProgressUpdate(boolean... go) { 
     if (go.equals(new Boolean(true))) { 
      sendMessage(); 
     } 

    } 

} 

這裏是ReceiverTask類:

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

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

public class ReceiverTask extends AsyncTask<EditText, MulticastSocket, Void> { 

    MulticastSocket so; 
    EditText messageBoard; 

    @Override 
    protected Void doInBackground(EditText... messBo) { 
     messageBoard = messBo[0]; 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(MulticastSocket... socket) { 
     so = socket[0]; 

     byte[] data = new byte[1024]; // received data container 

     while (true) { 
      try { 
       // create a datagram for receivin 
       DatagramPacket packet = new DatagramPacket(data, data.length); 

       // wait for the next message 
       so.receive(packet); 

       String message = new String(data, 0, packet.getLength()); 

       // add the new messages to the old ones 
       String conversation = messageBoard.getText().toString(); 
       String newConverstion = conversation.concat("\n[Remote] ").concat(message); 

       // 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 


      } catch (IOException ioe) {} 
     } 
    } 

} 

的錯誤是:

01-25 14:26:09.739: E/AndroidRuntime(661): FATAL EXCEPTION: main 
01-25 14:26:09.739: E/AndroidRuntime(661): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.regeduseroox.projx/com.regeduseroox.projx.Second}: java.lang.NullPointerException 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.ActivityThread.access$600(ActivityThread.java:123) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.os.Handler.dispatchMessage(Handler.java:99) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.os.Looper.loop(Looper.java:137) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.ActivityThread.main(ActivityThread.java:4424) 
01-25 14:26:09.739: E/AndroidRuntime(661): at java.lang.reflect.Method.invokeNative(Native Method) 
01-25 14:26:09.739: E/AndroidRuntime(661): at java.lang.reflect.Method.invoke(Method.java:511) 
01-25 14:26:09.739: E/AndroidRuntime(661): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
01-25 14:26:09.739: E/AndroidRuntime(661): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
01-25 14:26:09.739: E/AndroidRuntime(661): at dalvik.system.NativeStart.main(Native Method) 
01-25 14:26:09.739: E/AndroidRuntime(661): Caused by: java.lang.NullPointerException 
01-25 14:26:09.739: E/AndroidRuntime(661): at com.regeduseroox.projx.ReceiverTask.onProgressUpdate(ReceiverTask.java:33) 
01-25 14:26:09.739: E/AndroidRuntime(661): at com.regeduseroox.projx.SenderTask.setUp(SenderTask.java:53) 
01-25 14:26:09.739: E/AndroidRuntime(661): at com.regeduseroox.projx.SenderTask.doInBackground(SenderTask.java:27) 
01-25 14:26:09.739: E/AndroidRuntime(661): at com.regeduseroox.projx.Second.onCreate(Second.java:38) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.Activity.performCreate(Activity.java:4465) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) 
01-25 14:26:09.739: E/AndroidRuntime(661): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920) 
01-25 14:26:09.739: E/AndroidRuntime(661): ... 11 more 

ReceiverTask.java:33so.receive(packet);

SenderTask.java:53rec.onProgressUpdate(so);

SenderTask.java:27setUp();

Second.java:38snd.doInBackground(editTexts);

我不知道現在是錯誤的,我真的沒有想法瞭如何解決這個問題。任何幫助都感激不盡。

回答

1

更換

snd.doInBackground(editTexts); 

snd.execute(editTexts); 

編輯

你不應該直接調用onProgressUpdate()doInBackground()發起的AsyncTask,只有​​。此外,onProgressUpdate()在UI線程上工作,它僅用於更新ProgressBar。您應該將所有工作從onProgressUpdate()移至doInBackground(),並返回onPostExecute()中的數據。

我的建議是創建一個包含String(會話)和MulticastSocket(so)作爲其字段的自定義類。在您的AsyncTask.execute()調用中發送此對象,並從可變參數中檢索。

如:

public class MyObject { 
    MulticastSocket so; 
    EditText messageBoard; 

    //... Getters and Setters omitted for brevity 
} 

然後在您的SenderTask:

ReceiverTask rec = new ReceiverTask(); 
MyObject obj = new MyObject(so, messageBoard); 
rec.execute(obj); 

你應該用你的第二個/ SenderTask這個同樣的想法(取出的onProgressUpdate()工作)。

讓我知道這是不是都清楚,並且一定要重新讀取docs on the proper usage of AsyncTask.

+0

仍然有問題。它在ReceiveTask上產生NullPointer異常:so.receive(packet);和SenderTask:rec.onProgressUpdate(so);建立(); – RegedUser00x

+0

請看我更新的答案。 –

+0

謝謝,這似乎很有幫助。我現在只有一個問題 - 如何知道何時在doInBackground()內按下按鈕以發送消息? – RegedUser00x

0

它說在Second.java中有一個NullPointerException。在代碼中設置斷點,使用調試器,逐行掃描代碼,並查看斷點。我無法從錯誤告訴不夠好,但對我來說,它看起來像editText可能可能在

snd.doInBackground(editTexts); 

也爲空,如果你使用的是你應該使用服務器的multicast address不是IP地址多播套接字

+0

etHost和etPort確實是空根據調試器。不知道爲什麼這是如此,因爲一切似乎都很好。另外兩個EditTexts不是空的?什麼會造成這種情況? – RegedUser00x