Как использовать 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: только исходный поток, создавший иерархию представлений, может коснуться его представлений.

Как мне его изменить?

Ответ 1

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

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

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

Ответ 2

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

Все лучшие

Ответ 3

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

Ответ 4

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

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