ListActivityを継承したActivityクラスで、AsyncTaskで重い処理を行った後リストを更新するには

Androidアプリ開発において、時間のかかる処理を行うのにAsyncTaskを利用することがありますが、ListActivityで、リストの項目の削除、全削除をAsyncTaskで行い、削除後リストを更新するには一工夫が必要です。何も考えない場合、UIスレッドで、AsyncTask#executeの後、リスト更新を行ってしまいがちですが、AsyncTaskは非同期処理のため、executeを呼んだ直後にリスト更新が行われ、思うような動作になりません。

AsyncTaskでは、時間のかかる処理を終了後、onPostExecuteメソッドで終了処理を行います。このメソッド内で、リスト更新を行えばいいのですが、リスト更新処理内で、ArrayAdapterを継承したクラスのコンストラクタを呼んだり、ListActivity#setListActivity、ListView#setOnItemLongClickListenerを呼ぶには、AsyncTaskを継承したクラスに、Context、ListActivity、OnItemLongClickListener型のメンバ変数が渡されないといけません。そこで次のように実装をします。

AsyncTaskを継承したクラスHogeAsyncTaskで、コンストラクタを

public HogeAsyncTask(Context context, ListActivity listActivity,
      OnItemLongClickListener onIetmLongClickListener) {
    mContext = context;
    mListActivity = listActivity;
    mOnItemLongClickListener = onIetmLongClickListener;
    helper = new CreateProductHelper(mContext);
    dataDao = new DataDao(helper);
}

と定義して、ListActivityクラスを継承して、OnItemLongClickListenerインターフェースを実装したクラスFooAcitvityでは、

new HogeAsyncTask(FooActivity.this, FooActivity.this, FooActivity.this).execute();

で、AsyncTaskの処理を呼びます。そして、リスト更新は、AsyncTaskを継承したクラスのonPostExecute内で、

dataList = dataDao.select();
if (dataList != null) {
    mAdapter = new CustomAdapter(mContext, dataList);
    mListActivity.setListAdapter(mAdapter);
    ListView lv = mListActivity.getListView();
    lv.setOnItemLongClickListener(mOnItemLongClickListener);
}

で行います。なお、ここで書いたコードは断片コードですが、CreateProductHelperはSQLiteOpenHelperを継承したクラス、CustomAdapterはArrayAdapterを継承したクラスです。

Aug 21, 2012 追記
内容を修正したものを、「ListActivityを継承したActivityクラスで、AsyncTaskで重い処理を行った後リストを更新するには(改版)」に書きました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です