読者です 読者をやめる 読者になる 読者になる

ナカザンドットネット

Android Developer's memo

AsyncTaskLoaderを4ヶ月常用してみて

Android Programming

AsyncTaskLoaderに手を出してみる (d:id:Nkzn:20120113:1326478800) の続き。


とりあえず4ヶ月ほどAsyncTaskLoaderさんと仲良くしてみました。
色々あって、AsyncTaskさんとも少しだけ仲良くなりました。

ということで、現在の僕のAsyncTaskLoaderの使い方をメモしておきます。

public class AsyncSampleLoader extends AsyncTaskLoader<String> {
	
	private static final String tag = "AsyncSampleLoader";

	/**
	 * 呼び出し元からの値渡し用フィールド
	 */
	List<Hoge> mHogeParams;

	String result; // 定型
	
	public AsyncSampleLoader(Context context) {
		super(context);
		mHogeParams = new ArrayList<Hoge>();
	}

	public AsyncSampleLoader(Context context, Hoge hogeParams) {
		super(context);
		mHogeParams = hogeParams;
	}

	@Override
	public String loadInBackground() {
		String data = hogehogeAccessNetwork(mHogeParams); // 非同期にしたい処理本体
		return data;
	}

	/* ============以下、resultやdataの型以外は定型============ */

	@Override
	public void deliverResult(String data) {
		if (isReset()) {
			if (this.result != null) {
				this.result = null;
			}
			return;
		}

		this.result = data;

		if (isStarted()) {
			super.deliverResult(data);
		}
	}
	
	@Override
	protected void onStartLoading() {
		if (this.result != null) {
			deliverResult(this.result);
		}
		if (takeContentChanged() || this.result == null) {
			forceLoad(); // これをやっておくとonCreateLoaderで開始処理をしなくてよくなる
		}
	}
	
	@Override
	protected void onStopLoading() {
		super.onStopLoading();
		cancelLoad();
	}

	@Override
	protected void onReset() {
		super.onReset();
		onStopLoading();
	}
	
	@Override
	public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
	    super.dump(prefix, fd, writer, args);
	    writer.print(prefix); writer.print("result="); writer.println(this.result);
	}
}


結局 公式のサンプルと同じ感じになりました。
自分で書いてるのはコンストラクタとloadInBackground、それから各Overrideメソッド内の型パラメータ依存の型だけです。


呼び出し部分のコードも少しだけ書いておきます。(Activity内での実行を想定)

void startLoader() {
	getLoaderManager().initLoader(LOADER_ID, null, this);
	// コンパチの場合はgetSupportLoaderManager().initLoader(LOADER_ID, null, this);
}

@Override
public Loader<List<String>> onCreateLoader(int id, Bundle args) {
	return new AsyncSampleLoader(this, mHogeParams);
	// または new AsyncSampleLoader(this);
}

@Override
public void onLoadFinished(Loader<List<String>> loader, List<String> data) {
	/* dataを使った処理 */

	// restartLoaderの使い方がまだよく分かってないので、次回の読み込みでまたinitLoaderが使えるように一度殺しておく。
	getLoaderManager().destroyLoader(loader.getId());  // loader.getId() == LOADER_ID のはず
	// コンパチの場合はgetSupportLoaderManager().destroyLoader(loader.getId());
}

@Override
public void onLoaderReset(Loader<List<String>> loader) {
}


↑を書きながらrestartLoaderの使い方を調べてたら、公式のLoaderManagerのページに使い方っぽいものが載ってて、ちょっと理解し始めました。
ついでに今までイミフだったonLoaderResetの使い道もようやく分かった気がします。
実用してみて使い方がつかめたらまた記事を書こうと思います。

いろんな型のLoaderCallbacksを実装したい場合

今回紹介したのはStringでしたが、1つのActivityやFragmentの中で複数の型のデータを非同期に読み込みたい場合ってありますよね。
そんな場合のやりかたは、すますん先生(発想元はわかめん先生だけど)が紹介してくれていたので、こちらを使ってください。

1画面で複数AsyncTaskLoader
http://blog.livedoor.jp/ryosms/archives/5712827.html

このやり方なら、2つと言わずいくつでも対応できそうですね。


とりあえず今回はここまで。