Подтвердить что ты не робот

Обновление пользовательского интерфейса 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());
}

мое приложение продолжает сбой!

4b9b3361

Ответ 1

вы не можете трогать что-либо в потоке 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

Ответ 2

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

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

Ответ 3

Или просто используйте AsyncTask, это более полезно ИМХО.

Ответ 4

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

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

Ответ 5

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