AsyncTaskとAsyncTaskLoaderの考察

# はじめに
今更ですが、これまで非同期処理で便利なクラスとして活躍してきた **AsyncTask** と **AsyncTaskLoader** ですが、以前から使い分けについて悩みのタネでした。
Googleの公式としていつのまにか紹介されていたので、今回はこの２つのクラスの違いと使い所を考察してみます。

# 参考サイト
[7.1: AsyncTask and AsyncTaskLoader](https://google-developer-training.gitbooks.io/android-developer-fundamentals-course-concepts/content/en/Unit%203/71c_asynctask_and_asynctaskloader_md.html)

# ２つのクラス
そもそも、Googleはどのように紹介しているのか見てみます。

> There are two ways to do background processing in Android: using the AsyncTask class, or using the Loader framework, which includes an AsyncTaskLoader class that uses AsyncTask. In most situations you'll choose the Loader framework, but it's important to know how AsyncTask works so you can make a good choice.

意訳込みですが、バックグラウンド処理を行う際、 **AsyncTask** と **AsyncTaskLoader** を使用します。多くのケースでは「Loaderフレームワーク」を選択します。しかし、 **AsyncTask** の動きも理解しておく必要があります。両クラスの特徴を理解しておけば、正しい選択ができます。

ということは、基本的にLoaderフレームワークの **AsyncTaskLoader** を利用されることが前提になっているみたいです。

# AsyncTaskクラス
## 特徴
先ほどと同じように、Googleではどのように紹介されているか確認してみます。

> Use the AsyncTask class to implement an asynchronous, long-running task on a worker thread. (A worker thread is any thread which is not the main or UI thread.) AsyncTask allows you to perform background operations and publish results on the UI thread without manipulating threads or handlers.

またまた意訳込みですが、AsyncTaskクラスではバックグラウンド（UIスレッドやメインスレッドではない、ワーカースレッド）で長時間実行する処理を実装できます。
さらに、HanderやonUIThreadメソッドなどを使用しなくても、UIスレッド上で処理する内容を記述できます。

Googleもしっかりとメリットを伝えています。

## 制限事項
Googleでは下記の２点を制限事項として説明しています。

> AsyncTask is impractical for some use cases:
Changes to device configuration cause problems:

>When device configuration changes while an AsyncTask is running, for example if the user changes the screen orientation, the activity that created the AsyncTask is destroyed and re-created. The AsyncTask is unable to access the newly created activity, and the results of the AsyncTask aren't published.

>Old AsyncTask objects stay around, and your app may run out of memory or crash:

>If the activity that created the AsyncTask is destroyed, the AsyncTask is not destroyed along with it. For example, if your user exits the application after the AsyncTask has started, the AsyncTask keeps using resources unless you call cancel().

またまた意訳込みで説明を見ていきます。

* デバイスの構成を変更する動作が問題の原因に・・・
例えば、画面の向きが変わるとActivityが新規で作成されます。そのため、画面の向きを変更する前に実行したAsyncTaskでUIスレッド上の処理を実行しようとするとエラーが発生します。

* 古いタスクが残っている状態だとメモリー不足やメモリクラッシュの原因に・・・
AsyncTaskはActivityに紐付いているわけではないので、ユーザがアプリを終了させても動き続けます。そのときに、しっかりをAsyncTaskをキャンセルしておかないと、２重で実行してしまったり、メモリーが不足してしまったりします。必ずアプリが終了するときにキャンセルをしなければなりません。

なるほど、このような場合に、エラーとなり実行されてしまうのですね。
バックグラウンドで実行しているタスクはしっかりコントロールする必要がありそうです。

## 使い所
結果として、Googleは下記をAsyncTaskの使い所としています。

> When to use AsyncTask:

> Short or interruptible tasks.
 Tasks that don't need to report back to UI or user.
 Low-priority tasks that can be left unfinished.

意訳込みですが、下記のようになります。

*  短いもしくは、中断可能なタスクの場合
*  UIでユーザにタスクの状態を報告する必要がない場合
*  優先度が低く、タスクが未完の状態でも問題のないタスクの場合

ということは、簡単なタスクで使いなさいということですね。
ちなみに、その後にこんな記述があります。

> For all other situations, use AsyncTaskLoader, which is part of the Loader framework described next.

「上記のケース以外はAsyncTaskLoaderを使用します。」と書かれています。


# Loaders
ここの説明で、使い所の紹介がされています。

>Background tasks are commonly used to load data such as forecast reports or movie reviews. Loading data can be memory intensive, and you want the data to be available even if the device configuration changes. For these situations, use loaders, which are a set of classes that facilitate loading data into an activity.

意訳込みですが、基本的には事前のデータロードなどをAndroidアプリでは行うことあり、例えば、レポートとか動画のプレビューなどがあります。
また、このようなロードはメモリーを大量に使用するため、デバイスの構成が変わっても継続してデータを使用できるようにしておく必要があります。
この様なケースではLoaderが便利です。

なるほど、イメージが湧いてきました。
事前のロードなどのメモリに負荷がかかる様な処理は **AsyncTaskLoader** が便利だと言うことがわかりました。

# 結果（使い分け）

今回の結果は下記のようになることがわかりました。

|クラス|使い分け|具体例|
|:---|:---|:---|
| AsyncTask |・短いもしくは、中断可能なタスクの場合<br>・短いもしくは、中断可能なタスクの場合<br>・未完でも問題のないタスク|・スプラッシュ的な画面<br>・リストの画像表示<br>などなど|
| AsyncTaskLoader |事前にメモリへの読み込みが必要なデータのロード|・動画のレビュー<br>・レポートの作成<br>などなど|

# まとめ
これまでモヤモヤしていた両クラスの使い分けが理解できてスッキリしました。
これからはしっかり使い分けていけるようにしましょう！