Обновление пользовательского интерфейса Android с помощью потоков

Я пишу приложение для Android-андроида, я слушаю подключения и получаю данные, и я вижу его в Log.d, но всякий раз, когда я пытаюсь обновить свой интерфейс, сбой приложения .. код

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

И для обновления пользовательского интерфейса я использую:

 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 из фонового потока, для этого используйте Handlers, инициализируйте фоновый поток, передавая ему объект Handler. Когда данные поступают, используйте обработчик для отправки сообщения в ui. В ui, когда появляется сообщение из фонового потока, просто обновите представления.

что-то вроде этого…

В фоновом потоке:

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

И передайте обработчику в bakground thead

Вы не можете изменять элементы пользовательского интерфейса из потока, отличного от UI. Попробуйте использовать runOnUiThread .

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

Или просто используйте AsyncTask , он более полезен IMHO.

Используйте этот метод для обновления вашего пользовательского интерфейса из рабочего потока, здесь объясняется очень хорошо.

** Примечание. Если вы используете progressBar.setProgress (прогресс), вы можете обновлять непосредственно из рабочего потока, потому что встроенный метод ProgressBar вызывает встроенный метод setProgress () с помощью Handler. **