我有一個應用程序連接到遠程聊天服務器,然後用戶可以聊天。我有一個表單,用戶輸入主機名和端口,然後用戶可以看到所有消息並鍵入新消息。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:33
是so.receive(packet);
SenderTask.java:53
是rec.onProgressUpdate(so);
SenderTask.java:27
是setUp();
Second.java:38
是snd.doInBackground(editTexts);
我不知道現在是錯誤的,我真的沒有想法瞭如何解決這個問題。任何幫助都感激不盡。
仍然有問題。它在ReceiveTask上產生NullPointer異常:so.receive(packet);和SenderTask:rec.onProgressUpdate(so);建立(); – RegedUser00x
請看我更新的答案。 –
謝謝,這似乎很有幫助。我現在只有一個問題 - 如何知道何時在doInBackground()內按下按鈕以發送消息? – RegedUser00x