[Tips]AsyncTaskLoaderを使用した際のエラーハンドリング

2013.12.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AsyncTaskLoaderでのエラー処理

最近Androidで非同期処理を実行する場合、AsyncTaskLoaderを使用するのが一般的です。
HTTP通信等、非同期処理が必要な際によく使用していますが、
AsyncTaskLoader内で発生した例外は、外側のクラスでtry-catchを使用して捕まえることができません。
そのため、エラーハンドリング方法に悩んだ末にここで解決したので、その方法を紹介します。

AsyncTaskLoader

まずはシンプルなAsyncTaskLoaderを見てみましょう。
次の例は結果をStringで返すだけのシンプルなものです。

public class AsyncService extends AsyncTaskLoader<String> {
	@Override
	public String loadInBackground() {
		//ここでバッググラウンド処理を記述
		return "hello";
	}	
}

実行側では、LoaderCallbacksを実装したコールバックを使用することで、AsyncTaskLoaderを実行することができます。
※具体的な使いかたはここ参照

しかしこれでは、loadInBackground内で発生したエラーを呼び出し側でハンドリングすることができません。
ではどうするかというと、AsyncTaskLoaderのパラメータ引数に例外オブジェクトを抱合したオブジェクトを指定します。
まずはAsyncTaskLoaderから戻り値として返すための汎用的な用オブジェクトを定義します。

public class AsyncResult<D> {
	private Exception exception;
	private D data;

	public void setException(Exception exception) {
		this.exception = exception;
	}

	public Exception getException() {
		return exception;
	}

	public void setData(D data) {
		this.data = data;
	}

	public D getData() {
		return data;
	}

}

AsyncResultは型パラメータを1つとり、これがloadInBackgroundから本来返したい型を指定します。
loadInBackground内でエラーが発生した場合に例外をセットしておけば、呼び出し側でハンドリングできますね。

AsyncServiceを、AsyncResultを使用するように変更してみます。

public class AsyncService extends AsyncTaskLoader<AsyncResult<String>> {
	@Override
	public AsyncResult<String> loadInBackground() {
		AsyncResult res = new AsyncResult();
		//データをセット
		res.setData("hello");
		//エラーが発生したら例外オブジェクトセット
		res.setException(new Exception("error!"))
		return res;
	}	
}

呼び出し側では、戻り値に例外オブジェクトが存在するかどうかチェックすることで、
エラーがおこったかどうかを判定することができます。
こうすれば、エラー発生した場合にハンドリングすることが可能になりますね。

参考サイトなど