2017-07-30 167 views
0

我試圖運行與外部設備的UDP連接。我希望它每3秒向設備發送一條消息並閱讀響應。 我創建了3個類:主,發送者和接收者。 我爲發送者和接收者打開一個Runnable,讓他們在繼續之前休眠3秒。Android多線程UI更新

我的問題是,當我按下屏幕上的按鈕時,發送和接收的消息,但它們沒有在我的屏幕上更新,因爲更新行不在循環中。我如何告訴它每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(); 
     } 
    } 
} 
} 
+0

使用Handler to g o回到主線程,然後你可以更新你的TextView – MohammedAlSafwan

回答

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

收到消息,在任何類,它是在另一個線程,嘗試這樣做

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

handler.post(new Runnable(){ 
     // your TextView goes here 
}) 
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); 
    } 
}); 
...