データを更新するスレッドを作成し、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:ビュー階層を作成した元のスレッドのみがそのビューにアクセスできます。
どうすれば修正できますか?
UI以外のスレッドからUIアクションを実行するには、runOnUiThread()
メソッドを使用します。
private class ReceiverThread extends Thread {
@Override
public void run() {
Activity_name.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
他のスレッドからUIのビューに触れることはできません。あなたの問題については、あなたはAsyncTask、runOnUiThreadまたはhandlerのいずれかを使用できます。
ではごきげんよう
他のスレッドからUIスレッドにアクセスすることはできません。これを実行するには、ハンドラーを使用する必要があります。runメソッド内でハンドラーにメッセージを送信し、ハンドラー内でUIを更新(mAdapter.notifyDataSetChanged()を呼び出す)できます。
Activity.runOnUiThread(実行可能)
View.post(実行可能)
View.postDelayed(実行可能、長い)
私が仕事に他のスレッドを使用するときの私のアプローチ:
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();
}
}
});
}
}
btwnotifyDatasetChanged()メソッドは、AbsListView.setAdaptert(Adapter)メソッドにAdapter.registerDataSetObserverへのコールバックを設定することによって最初に設定されるAbsListViewのDataSetObservableクラスオブジェクトにフックします。 (DataSetObserver);
このように書くこともできます。
new Handler().postDelayed(new Runnable() {
public void run() {
test();
}
}, 100);
private void test() {
this.notifyDataSetChanged();
}
ただそれをテストしてください。