Android3.0(HoneyComb)から、AndroidにはLoaderという非同期にデータをロードする仕組みが追加されています。
本エントリでは、そのLoaderの仕組みの中でもAsyncTaskに似た汎用的なLoaderのAsyncTaskLoaderの使い方を紹介しています。
以下スクリーンショットの様な、端末内のアプリケーション一覧を読み込むアプリケーションを作成し、
AsyncTaskLoaderを紹介していきます。
本サンプルは、Android Developersのサンプルを参考に処理を簡略化しています。
AsyncTaskLoaderを深く理解するために、リンク先も参考にするとよいと思います。
それでは続きをどうぞ。
AsyncTaskLoaderを利用する
はじめにAsyncTaskLoaderを利用する場合の重要なメソッドを以下に纏めます。
以下に挙げたメソッドはどれも必ず実装しなければならないものです。
LoaderCallbacksインターフェース
Loaderを呼び出すActivityやFragmentにimplementsするインターフェースです。
[table “199” not found /]AsyncTaskLoaderクラスのメソッド
AsyncTaskLoaderクラスのメソッドとして、必ずOverrideし作成しなければならないメソッドは以下の一つです。
[table “200” not found /]AsyncTaskLoaderを継承したクラスを用意する
早速、AsyncTaskLoaderを継承したクラスを用意しましょう。
AsyncTaskLoaderは抽象クラスのため、継承して利用します。
AsyncTaskLoaderを継承したクラスの作成方法の具体例は、以下サンプルをご覧下さい。
■ApplicationListLoader.java
public class ApplicationListLoader extends AsyncTaskLoader<List<ApplicationListItem>> { //省略..... @Override public List<ApplicationListItem> loadInBackground() { //省略..... }
作成するAsyncTaskLoaderを継承したクラスでは、バックグラウンドでの処理実行結果を返す型を指定する必要があります。
上記サンプルソースコードの1行目、6行目に注目してください。
サンプルソースコードではList
バックグラウンド処理を記述する
作成したAsyncTaskLoaderを継承したクラスのloadInBackgroundメソッド内にバックグラウンドで実行する処理を記述します。
loadInBackgroundメソッドの実行後、Activity/Fragmentに実装するonLoadFinishedメソッドが呼び出されます。
onLoadFinishedメソッドでAsyncTaskLoaderの実行結果を利用する場合には、loadInBackgroundメソッドのreturnに指定しましょう。
onLoadFinishedメソッドの第二引き数として取得することができます。
本サンプルでは、バックグラウンドで端末にインストールされたアプリケーション一覧を取得しています。
該当の処理は以前にTechBoosterで紹介した内容でもありますので、詳細はそちらを確認ください。
インストール済みアプリケーションのアプリケーション名とアイコンを取得する
リストビューをカスタマイズする
loadInBackgroundメソッドの処理は以下の通りです。
前述の通り、アプリケーションの一覧をPackageManagerから取得し、
Listアイテムの管理用に作成したApplicationListItemクラスに挿入しています。
■ApplicationListLoader.java
@Override public List<ApplicationListItem> loadInBackground() { // Application一覧の取得 List<ApplicationInfo> appInfoList = pm.getInstalledApplications(Context.BIND_AUTO_CREATE); // Application一覧の読み込み List<ApplicationListItem> ret = new ArrayList<ApplicationListItem>(appInfoList.size()); for(ApplicationInfo info : appInfoList){ ApplicationListItem item = new ApplicationListItem(info); try { // nameの追加 item.setName(info.loadLabel(pm).toString()); // Iconの追加 item.setIcon(pm.getApplicationIcon(info.packageName)); } catch (NameNotFoundException e) { e.printStackTrace(); } ret.add(item); } return ret; }
2行目でloadInBackgroundメソッドの戻り値を指定しています。
ここで、onLoadFinishedメソッドで利用する型を宣言しておきましょう。
本サンプルでは、インストールされたアプリケーションをリスト表示するためのList型をreturnしています。
Loaderを呼び出す
Activity、またはFragmentからLoaderを呼び出す事ができます。
Loaderを呼び出すActivity/Fragmentには、LoaderCallbacksインターフェースをimplementsする必要があります。
実装しなければならないメソッドは冒頭の表でも触れた通り、onCreateLoaderメソッド、onLoadFinishedメソッド、onLoaderResetメソッドの3つです。
サンプルでの3つのメソッドの実装は以下の通りになっています。
■LoaderSampleActivity.java
public class LoaderSampleActivity extends Activity implements LoaderCallbacks<List<ApplicationListItem>>{ ApplicationListAdapter mAdapter; // 省略...(下記にて別途引用) // onCreateメソッド /** * Loaderの開始処理 */ @Override public Loader<List<ApplicationListItem>> onCreateLoader(int id, Bundle args) { ApplicationListLoader appLoader = new ApplicationListLoader(getApplication()); // loaderの開始 appLoader.forceLoad(); return appLoader; } /** * Loaderの処理終了コールバック */ @Override public void onLoadFinished(Loader<List<ApplicationListItem>> arg0, List<ApplicationListItem> arg1) { // リスト表示するAdapterにアイテムをセット for(ApplicationListItem item : arg1){ mAdapter.add(item); } // リスト表示の更新 mAdapter.notifyDataSetChanged(); } /** * Loaderがリセットされた時によびだされる */ @Override public void onLoaderReset(Loader<List<ApplicationListItem>> arg0) { // 今回は無視する }
11行目、23行目、38行目でそれぞれLoaderCallbacksインターフェースのメソッドをOverrideしています。
15行目でLoaderクラスのforceLoadメソッドを呼び出し、Loaderの処理を開始させています。
forceLoadメソッドの呼び出しはプロセスのメインスレッドで行う必要があります。
また、Callbackメソッドを用意する以外にLoaderの初期化処理を行う必要があります。
初期化処理はLoaderManagerクラスのinitLoaderメソッドを利用して行います。
Loaderの初期化処理のサンプルは以下の通りです。
■LoaderSampleActivity.java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView list = (ListView)findViewById(R.id.listView1); mAdapter = new ApplicationListAdapter(this, android.R.layout.simple_list_item_1); list.setAdapter(mAdapter); // loaderの初期化 getLoaderManager().initLoader(0, null, this); }
11行目でLoaderの初期化処理を行っています。
ActivityクラスのgetLoaderManagerメソッドでLoaderManagerクラスのインスタンスを取得し、initLoaderメソッドを呼び出しています。
initLoaderクラスのメソッドの引数は、次のとおりになります。