Android AsyncTask и сеть Mayham - PullRequest
       3

Android AsyncTask и сеть Mayham

0 голосов
/ 25 января 2012

У меня есть приложение, которое подключается к удаленному серверу чата, а затем пользователь может общаться в чате.У меня есть форма, где пользователь вводит имя хоста и порт, а затем другая форма, где пользователь видит все сообщения и вводит новые.

Кажется, что для работы в сети у меня нет другого выбора, кроме как использовать AsyncTask.Но есть кое-что, что я не знаю, как сделать.Я бы начал сеть в пользовательском интерфейсе, когда вызывается onCreate (), что не является проблемой.Но потом, когда мне нужно подключить сеть и интерфейс, это становится беспорядком.Я создал две асинхронные задачи - одну для отправки и одну для получения, но у меня это не работает.Вот код, с которого я сначала запускаю 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);

Я не знаю, что сейчас не так, и яна самом деле больше нет идей, как это решить.Любая помощь будет высоко ценится.

Ответы [ 2 ]

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

Заменить

snd.doInBackground(editTexts);

с

snd.execute(editTexts);

EDIT

Вы не должны напрямую звонить onProgressUpdate() или doInBackground(), чтобы инициировать AsyncTask, только execute(). Кроме того, onProgressUpdate() работает с потоком пользовательского интерфейса, который на самом деле предназначен только для обновления ProgressBar. Вы должны переместить всю работу с onProgressUpdate() на doInBackground() и вернуть данные в onPostExecute().

Я предлагаю создать пользовательский класс, включающий String (разговор) и MulticastSocket (так) в качестве полей. Отправьте этот объект в вашем AsyncTask.execute() вызове и получите из varargs.

Например:

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);

Вы должны использовать эту же идею для своей Second / SenderTask (возьмите работу из onProgressUpdate()).

Дайте мне знать, если это все ясно, и обязательно перечитайте документы по правильному использованию AsyncTask.

0 голосов
/ 25 января 2012

Он говорит, что в Second.java есть исключение NullPointerException.Установите точку останова в своем коде, используйте отладчик, построчно просматривайте код и смотрите, где он ломается.Я не могу сказать достаточно по ошибке, но мне кажется, что editText может быть нулевым в

snd.doInBackground(editTexts);

Также, если вы используете многоадресные сокеты, вы должны использовать адрес многоадресной рассылки не IP-адрес сервера

...