web-dev-qa-db-ja.com

スレッドでnotifyDataSetChanged()を使用する方法

データを更新するスレッドを作成し、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:ビュー階層を作成した元のスレッドのみがそのビューにアクセスできます。

どうすれば修正できますか?

27
brian

UI以外のスレッドからUIアクションを実行するには、runOnUiThread()メソッドを使用します。

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

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

他のスレッドからUIのビューに触れることはできません。あなたの問題については、あなたはAsyncTaskrunOnUiThreadまたはhandlerのいずれかを使用できます。

ではごきげんよう

6
Richa

他のスレッドからUIスレッドにアクセスすることはできません。これを実行するには、ハンドラーを使用する必要があります。runメソッド内でハンドラーにメッセージを送信し、ハンドラー内でUIを更新(mAdapter.notifyDataSetChanged()を呼び出す)できます。

4

他のスレッドからUIスレッドにアクセスする

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

1
ceph3us

このように書くこともできます。

  new Handler().postDelayed(new Runnable() {
                public void run() {
                    test();
                }
            }, 100);

private void test() {
    this.notifyDataSetChanged();
}

ただそれをテストしてください。