[Tips]AsyncTaskLoaderを使用した際のエラーハンドリング
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; } }
呼び出し側では、戻り値に例外オブジェクトが存在するかどうかチェックすることで、 エラーがおこったかどうかを判定することができます。 こうすれば、エラー発生した場合にハンドリングすることが可能になりますね。
参考サイトなど
- Android: AsyncTaskLoader Exception Handling: http://blog.gunawan.me/2011/10/android-asynctaskloader-exception.html