Как использовать notifyDataSetChanged() в потоке

Я создаю тему, чтобы обновить свои данные и пытаюсь сделать notifyDataSetChanged в моем ListView.

private class ReceiverThread extends Thread {

@Override
public void run() { 
    //up-to-date
    mAdapter.notifyDataSetChanged();
}

Ошибка возникает в строке:

mAdapter.notifyDataSetChanged();

Ошибка:

12-29 16: 44: 39.946: E / AndroidRuntime (9026): android.view.ViewRoot $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться его представлений.

Как я должен изменить это?

4 ответа

Решение

Использование runOnUiThread() метод для выполнения действия пользовательского интерфейса из потока не-пользовательского интерфейса.

private class ReceiverThread extends Thread {
@Override
public void run() { 
Activity_name.this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
             mAdapter.notifyDataSetChanged();
        }
    });
}

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

Всего наилучшего

Вы не можете получить доступ к потоку пользовательского интерфейса из другого потока. Для этого вам нужно использовать обработчик. Вы можете отправить сообщение обработчику внутри вашего метода run и обновить интерфейс (вызвать mAdapter.notifyDataSetChanged()) внутри обработчика.

получить доступ к потоку пользовательского интерфейса из других потоков

Activity.runOnUiThread (Runnable)

View.post (Runnable)

View.postDelayed (Runnable, long)

мой подход, когда я использую другие темы для работы:

private AbsListView _boundedView;
private BasicAdapter _syncAdapter;

 /** bind view to adapter */
public void bindViewToSearchAdapter(AbsListView view) {
    _boundedView = view;
    _boundedView.setAdapter(_syncAdapter);
}

/** update view on UI Thread */
public void updateBoundedView() {
    if(_boundedView!=null) {
        _boundedView.post(new Runnable() {
            @Override
            public void run() {
                if (_syncAdapter != null) {
                    _syncAdapter.notifyDataSetChanged();
                }
            }
        });
    }
}

btw метод notifyDatasetChanged() подключается к объекту класса DataSetObservable класса AbsListView, который сначала устанавливается с помощью метода AbsListView.setAdaptert(Adapter) путем установки обратного вызова в Adapter.registerDataSetObserver(DataSetObserver);

Вы также можете писать таким образом.

  new Handler().postDelayed(new Runnable() {
                public void run() {
                    test();
                }
            }, 100);

private void test() {
    this.notifyDataSetChanged();
}

просто проверьте это.

Другие вопросы по тегам