Android多线程UI更新

时间:2017-07-30 14:09:35

标签: java android multithreading udp

我试图与外部设备运行UDP连接。我希望它每隔3秒向设备发送一条消息并阅读响应。 我创建了3个类:main,sender和receive。 我为发送者和接收者打开一个Runnable,让他们在继续之前睡3秒钟。

我的问题是,当我按下屏幕上的按钮时,会发送和接收消息,但是由于更新行不在循环中,因此它们不会在我的屏幕上更新。我怎么告诉它每隔3秒更新一次屏幕?读取消息并显示它的代码是:

textViewState.setText(udpReceive.receivedMessage);

代码

public class MainActivity extends AppCompatActivity {

public static TextView textViewState;
public static Context context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textViewState = (TextView) findViewById(R.id.textView);
    context = getApplicationContext();

}

public void buttonConnect(View v) {

    (new Thread(new udpSender())).start();

    (new Thread(new udpReceive())).start();

    textViewState.setText(udpReceive.receivedMessage);

}


}

发送消息的类:

public class udpSender implements Runnable {


public void run() {

    while (true) {

        String messageStr = "Hello Android!";
        int server_port = 8888;
        DatagramSocket s = null;
        try {
            s = new DatagramSocket();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        InetAddress local = null;
        try {
            local = InetAddress.getByName("192.168.43.159");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        int msg_length = messageStr.length();
        byte[] message = messageStr.getBytes();

        DatagramPacket p = new DatagramPacket(message, msg_length, local, server_port);
        try {
            s.send(p);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
}

从udp接收消息的类

public class udpReceive implements Runnable {

private static final int MAX_UDP_DATAGRAM_LEN = 100;
private static final int UDP_SERVER_PORT = 8888;
public static String receivedMessage;

public void run() {


    while (true) {
        String message;
        byte[] lmessage = null;
        lmessage = new byte[MAX_UDP_DATAGRAM_LEN];
        DatagramPacket packet = null;

        DatagramSocket socket = null;
        try {
            packet = new DatagramPacket(lmessage, lmessage.length);
            socket = new DatagramSocket(UDP_SERVER_PORT);
            socket.receive(packet);
            message = new String(lmessage, 0, packet.getLength());
            receivedMessage = message;
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                socket.close();
            }
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}

3 个答案:

答案 0 :(得分:0)

在另一个线程中的任何类中,尝试执行此操作

Handler handler = new Handler(getActivity().getMainLooper());

handler.post(new Runnable(){
      // your TextView goes here
})

答案 1 :(得分:0)

只有UI线程(主线程)可以访问UI元素

// Your message receiving class
...
message = new String(lmessage, 0, packet.getLength());
final String message_received = new String(lmessage, 0, packet.getLength());
...

MainActivity.context.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        MainActivity.textViewState.setText(message_received);
    }
});
...

答案 2 :(得分:0)

我找到了一个基于你的答案的解决方案:)谢谢

MainActivity类:

public static Handler UIHandler;

static {
    UIHandler = new Handler(Looper.getMainLooper());
}

public static void runOnUI(Runnable runnable) {
    UIHandler.post(runnable);
}

收到课程

MainActivity.runOnUI(new Runnable() {
    public void run() {
         MainActivity.textViewState.setText(message_received);
    }
});