Как использовать notifyDataSetChanged () в потоке - PullRequest
27 голосов
/ 29 декабря 2011

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

private class ReceiverThread extends Thread {

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

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

mAdapter.notifyDataSetChanged();

Error

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

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

Ответы [ 4 ]

45 голосов
/ 29 декабря 2011

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

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

        @Override
        public void run() {
             mAdapter.notifyDataSetChanged();
        }
    });
}
6 голосов
/ 29 декабря 2011

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

Все лучшее

4 голосов
/ 29 декабря 2011

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

1 голос
/ 02 июля 2015

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...