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で重い処理を行った後リストを更新するには(改版)」に書きました。