これは非常に良い質問です。Android プログラマーとして問題を完全に理解するには時間がかかります。実際、AsyncTask には関連する 2 つの主な問題があります。
- アクティビティのライフ サイクルとの関連性が低い
- それらはメモリリークを非常に簡単に作成します。
RoboSpice Motivations アプリ ( Google Play で入手可能)内で、その質問に詳しく答えます。AsyncTasks、ローダー、それらの機能と欠点の詳細なビューを提供し、ネットワーク リクエストの代替ソリューションである RoboSpice も紹介します。ネットワーク リクエストは Android の一般的な要件であり、本質的に長時間実行される操作です。アプリからの抜粋は次のとおりです。
AsyncTask とアクティビティのライフ サイクル
AsyncTask は、Activity インスタンスのライフ サイクルに従いません。アクティビティ内で AsyncTask を開始し、デバイスを回転させると、アクティビティが破棄され、新しいインスタンスが作成されます。しかし、AsyncTask は死ぬことはありません。完成するまで生き続けます。
そして完了すると、AsyncTask は新しいアクティビティの UI を更新しません。実際、表示されなくなったアクティビティの以前のインスタンスを更新します。たとえば、findViewById を使用してアクティビティ内のビューを取得すると、java.lang.IllegalArgumentException: View not attached to window manager というタイプの例外が発生する可能性があります。
メモリリークの問題
アクティビティの内部クラスとして AsyncTasks を作成すると非常に便利です。AsyncTask は、タスクが完了または進行中のときに Activity のビューを操作する必要があるため、Activity の内部クラスを使用すると便利なようです。内部クラスは、外部クラスの任意のフィールドに直接アクセスできます。
それにもかかわらず、内部クラスがその外部クラスのインスタンスである Activity.
長期的には、これによりメモリ リークが発生します。AsyncTask が長時間続くと、アクティビティが「生きている」状態に保たれますが、Android はアクティビティを表示できなくなったため、削除したいと考えています。アクティビティはガベージ コレクションできません。これは、Android がデバイス上のリソースを保持するための中心的なメカニズムです。
長時間実行される操作に AsyncTasks を使用することは、非常に悪い考えです。それでも、1 秒または 2 秒後にビューを更新するなどの短命のものには問題ありません。
RoboSpice Motivations アプリをダウンロードすることをお勧めします。これは、これについて詳しく説明し、いくつかのバックグラウンド操作を実行するさまざまな方法のサンプルとデモを提供します。