Как использовать 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();
}
просто проверьте это.