- Date: Sun 06 10 2013
- Category: Android
- Response: Comment 0 Trackback 0
非同期処理:AsyncTaskLoader
AsyncTaskLoader は Android で用意された非同期処理に特化したスレッドクラスです。
AsyncTaskLoader クラスは Android 3.0 (API 11) から追加された Loader クラスのサブクラスで、以前「非同期処理:AsyncTask」で紹介した AsyncTask を内包しています。
Android 3.0 で追加されていますが Android Support Library に含まれているため、Android 3.0 以前でも利用できます。
Android Support Library の場合、Loader を実行するために必要な getSupportLoaderManager が FragmentActivity に実装されているため、呼び出し元のアクティビティは FragmentActivity を継承する必要があります。
AsyncTaskLoader と AsyncTask の違いは UI 処理をどこで行うかにあります。
AsyncTask では非同期処理の実行前後の UI 処理は AsyncTask クラス内に定義していましたが
AsyncTaskLoader では LoaderCallbacks インターフェイスを介して行われるため、非同期処理の実行前後の UI 処理も Activity 内に定義できるようになりました。
これにより UI 処理は Activity 側、非同期処理は AsyncTaskLoader 側と住み分けができるようになっています。

■ ソースコードで定義
次のサンプルコードでは Android Support Library の AsyncTaskLoader を使っています。
① FragmentActivity#getSupportLoaderManager().initLoader()
② LoaderCallbacks#onCreateLoader()
③ AsyncTaskLoader#onStartLoading()
④ AsyncTaskLoader#loadInBackground()
⑤ LoaderCallbacks#onLoadFinished() ※キャンセル時は AsyncTaskLoader#onCanceled()
④の非同期処理は③で AsyncTaskLoader#forceLoad() を呼ぶ必要があります。
呼ばなかった場合、非同期処理は行われません(…ここで少しはまりました…)
■ 参考サイト
ソフトウェア技術ドキュメントを勝手に翻訳 - 1.2 ローダ
TechBooster - AsyncTaskLoaderを利用した非同期処理を行う
クラスメソッド Developers.IO - AsyncTaskLoaderを使ってみる
コジオニルク - 1.11. AsyncTaskLoader
AsyncTaskLoader クラスは Android 3.0 (API 11) から追加された Loader クラスのサブクラスで、以前「非同期処理:AsyncTask」で紹介した AsyncTask を内包しています。
Android 3.0 で追加されていますが Android Support Library に含まれているため、Android 3.0 以前でも利用できます。
Android Support Library の場合、Loader を実行するために必要な getSupportLoaderManager が FragmentActivity に実装されているため、呼び出し元のアクティビティは FragmentActivity を継承する必要があります。
AsyncTaskLoader と AsyncTask の違いは UI 処理をどこで行うかにあります。
AsyncTask では非同期処理の実行前後の UI 処理は AsyncTask クラス内に定義していましたが
AsyncTaskLoader では LoaderCallbacks インターフェイスを介して行われるため、非同期処理の実行前後の UI 処理も Activity 内に定義できるようになりました。
これにより UI 処理は Activity 側、非同期処理は AsyncTaskLoader 側と住み分けができるようになっています。

■ ソースコードで定義
次のサンプルコードでは Android Support Library の AsyncTaskLoader を使っています。
package jp.inujirushi.android.sample;非同期処理の流れ
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.widget.Toast;
public class SampleActivity extends FragmentActivity implements
LoaderCallbacks<Boolean> {
// Activity が生成された時に呼ばれます
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
// Loader を実行する
// 第2引数で onCreateLoader に渡される Bundle を指定するがこのサンプルでは使用しないので null
getSupportLoaderManager().initLoader(0, null, this);
}
// Loader を新規作成する時に呼ばれます。
// 戻り値には実行する Loader を指定してください。
// AsyncTask#onPreExecute() で行っていた処理もここに記述します。
@Override
public Loader<Boolean> onCreateLoader(int id, Bundle bundle) {
// ProgressDialog を生成する
TestProgressDialog dialog = new TestProgressDialog();
Bundle args = new Bundle();
args.putString(TestProgressDialog.PARAM_MESSAGE, "now loaging...");
dialog.setArguments(args);
// ProgressDialog をキャンセルしたら Loader もキャンセルするよう設定する
dialog.setCancelable(true);
dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Loader<Object> loader = getSupportLoaderManager().getLoader(0);
// Loader をキャンセルする
if (loader != null) {
((AsyncTaskLoader<?>) loader).cancelLoad();
}
}
});
// ProgressDialog を表示する
dialog.show(getSupportFragmentManager(), "progress");
// 生成した Loader を返します
return new SampleAsyncTaskLoader(this);
}
// Loader の処理が完了した時に呼ばれます。
// キャンセル時には呼ばれません。
// AsyncTask#onPostExecute() で行っていた処理はここに記述します。
@Override
public void onLoadFinished(Loader<Boolean> loader, Boolean result) {
// ProgressDialog を破棄する
TestProgressDialog dialog = (TestProgressDialog) getSupportFragmentManager()
.findFragmentByTag("progress");
if (dialog != null) {
dialog.onDismiss(dialog.getDialog());
}
// 結果をトースト表示する
Toast.makeText(this, "result=" + result, Toast.LENGTH_SHORT).show();
}
// Loader が完全に破棄される時に呼ばれます。
@Override
public void onLoaderReset(Loader<Boolean> loader) {
}
/**
* Loader 処理クラス。
*/
static class SampleAsyncTaskLoader extends AsyncTaskLoader<Boolean> {
/**
* コンストラクタ。
* @param context
* コンストラクタ
*/
public SampleAsyncTaskLoader(Context context) {
super(context);
}
// 非同期処理を行います。
// キャンセル有無にかかわらず処理は最後まで流れます。
@Override
public Boolean loadInBackground() {
// 10秒間処理をしているように見せかけるためスリープ
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
return true;
}
// キャンセルされた時に呼ばれます。
// この処理は loadInBackground() の完了後に行われます。
@Override
public void onCanceled(Boolean data) {
}
// Loader が開始された時に呼ばれます。
@Override
protected void onStartLoading() {
// Loader を開始する
forceLoad();
}
}
}
① FragmentActivity#getSupportLoaderManager().initLoader()
② LoaderCallbacks#onCreateLoader()
③ AsyncTaskLoader#onStartLoading()
④ AsyncTaskLoader#loadInBackground()
⑤ LoaderCallbacks#onLoadFinished() ※キャンセル時は AsyncTaskLoader#onCanceled()
④の非同期処理は③で AsyncTaskLoader#forceLoad() を呼ぶ必要があります。
呼ばなかった場合、非同期処理は行われません(…ここで少しはまりました…)
■ 参考サイト
ソフトウェア技術ドキュメントを勝手に翻訳 - 1.2 ローダ
TechBooster - AsyncTaskLoaderを利用した非同期処理を行う
クラスメソッド Developers.IO - AsyncTaskLoaderを使ってみる
コジオニルク - 1.11. AsyncTaskLoader
スポンサーサイト