【问题标题】:How to use notifyDataSetChanged() in thread如何在线程中使用 notifyDataSetChanged()
【发布时间】:2011-12-29 08:50:52
【问题描述】:
我创建了一个线程来更新我的数据并尝试在我的 ListView 上执行notifyDataSetChanged。
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: 只有创建视图层次结构的原始线程才能接触其视图。
我应该如何修改它?
【问题讨论】:
标签:
android
listview
android-listview
【解决方案1】:
使用 runOnUiThread() 方法从非 UI 线程执行 UI 操作。
private class ReceiverThread extends Thread {
@Override
public void run() {
Activity_name.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
【解决方案2】:
您不能从其他线程触摸 UI 的视图。对于您的问题,您可以使用 AsyncTask、runOnUiThread 或 handler。
一切顺利
【解决方案3】:
您不能从其他线程访问 UI 线程。您必须使用处理程序来执行此操作。您可以在运行方法中向处理程序发送消息并在处理程序内部更新 UI(调用 mAdapter.notifyDataSetChanged())。
【解决方案4】:
access the UI thread from other threads
Activity.runOnUiThread(可运行)
View.post(可运行)
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() 方法挂钩到 AbsListView 的 DataSetObservable 类对象,该对象首先通过涉及 AbsListView.setAdaptert(Adapter) 方法设置回调到 Adapter.registerDataSetObserver(DataSetObserver);
【解决方案5】:
你也可以这样写。
new Handler().postDelayed(new Runnable() {
public void run() {
test();
}
}, 100);
private void test() {
this.notifyDataSetChanged();
}
只是测试一下。