使用线程更新Android UI

我正在写一个Android聊天应用程序。 我正在监听连接,我收到数据,我可以在Log.d看到它,但每当我尝试更新我的UI时,应用程序崩溃。

代码段:

 private class chatReceiver implements Runnable { @Override public void run() { try { skt = new DatagramSocket(Integer.parseInt(Main.prefs.getString("port_number", "5432"))); DatagramPacket rcvPkt = new DatagramPacket(rcvBuf,rcvBuf.length); String ack = "Hello from our SimpleUDPServer"; byte[] sndBuf = ack.getBytes(); while (true) { Log.d("Server received: " ,"entered loop"); skt.receive(rcvPkt); String rcvMsg = new String(rcvBuf, 0, rcvPkt.getLength(), "UTF-8"); Log.d("Server received: " ,"receiving" + rcvMsg); if (rcvMsg != null) { Log.d("Server received: " ,"not equal null"); // I want to update my UI here } DatagramPacket k = new DatagramPacket(sndBuf, sndBuf.length, rcvPkt.getAddress(), rcvPkt.getPort()); skt.send(k); Log.d("Server sent" ,ack); } } catch (IOException ex) { Log.d("ThreadStart", "Error Starting thread" + ex.getStackTrace()); } } } 

并更新我使用的UI:

 public static void updateUI(Bubble b, View itemView) { TextView txt_display_name = (TextView) itemView .findViewById(R.id.display_name); txt_display_name.setText(b.getDisplay_name()); TextView txt_chat_body = (TextView) itemView .findViewById(R.id.chat_body); txt_chat_body.setText(b.getChat_body()); TextView txt_creation_date = (TextView) itemView .findViewById(R.id.creation_date); txt_creation_date.setText(b.getCreation_time()); } 

应用程序不断崩溃。

Solutions Collecting From Web of "使用线程更新Android UI"

您无法从后台线程触摸UI线程中的任何内容,为此使用Handlers ,初始化后台thread并将其传递给Handler对象。 当数据到达时使用handler向UI发送消息。 在UI中,来自后台thread的消息到来时,只需更新Views

示例代码段:

在后台线程中:

 if(dataArrives){ Message msg = handler.obtainMessage(); msg.what = UPDATE_IMAGE; msg.obj = bitmap; msg.arg1 = index; handler.sendMessage(msg); } 

在UI线程中:

 final Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==UPDATE_IMAGE){ images.get(msg.arg1).setImageBitmap((Bitmap) msg.obj); } super.handleMessage(msg); } }; 

并将handler传递给后台thread

您无法从非UI线程更改UI元素。 尝试使用runOnUiThread 。

 runOnUiThread(new Runnable(){ @Override public void run(){ // change UI elements here } }); 

或者只是使用AsyncTask ,它更有用恕我直言。

 private void yourMethodName(){ new Thread(new Runnable() { @Override public void run() { try { //do some heavy task here on main separate thread like: Saving files in directory, any server operation or any heavy task ///Once this task done and if you want to update UI the you can update UI operation on runOnUiThread method like this: homeActivity.runOnUiThread(new Runnable() { @Override public void run() { txtview.setText("some value"); edittext.setText("some new value"); } }); } catch (Exception e) { //print the error here } } }).start(); } 

使用此方法从工作线程更新UI,这里解释得很好。

注意: – 如果使用progressbar.setProgress(progress) ,则可以直接从工作thread更新,因为ProgressBar内部使用Handler调用setProgress()方法。