LocalBroadcastを使ってAsyncTaskLoaderでProgressの通知を実装する
AsyncTaskLoaderにはAsyncTaskのpublishProgress()
のような途中経過を通知するメソッドが標準では用意されていません。
そこでブロードキャストを利用してこれを実装します。
Context#sendBroadcast()
を使ってもいいのですが、これだと自分のアプリ外にもブロードキャストが送信されてしまうので、LocalBroadcastManager
を利用します。
AsyncTaskLoader側ではloadInBackground()
内で、ブロードキャストの送信を行うだけです。
この際、途中経過のデータはIntentに埋め込んで送信する必要があります。
@Override
public String loadInBackground(){
//非同期処理
Intent intent = new Intent(MainActivity.ACTION_PROGRESS)
.putExtra("key", "hoge");
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
MainActivity.ACTION_PROGRESS
はインテントフィルタを表す文字列です。
//インテントフィルタの定義
public static final String ACTION_PROGRESS = "jp.gcreate.sample.asynctaskloadersample.ACTION_PROGRESS";
//ブロードキャストレシーバーの作成
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String progress = intent.getStringExtra("key");
mTextView.setText(progress);
}
};
@Override
protected void onStart() {
super.onStart();
//ブロードキャストレシーバーの登録
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
manager.registerReceiver(mReceiver, new IntentFilter(ACTION_PROGRESS));
}
@Override
protected void onStop() {
super.onStop();
//ブロードキャストレシーバーの解除
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
}
ブロードキャストレシーバーを作成して、ここでAsyncTaskLoaderから送られてくるProgressを受け取りとUIの更新処理を実装します。
後はonStart()
でブロードキャストレシーバーの登録、onStop()
で解除を行ってやればOKです。
細かいサンプルはGitHubにおいてます。