← ホームへ戻る

AsyncTask、Loader、Rx、Coroutinesを全部通って見えた Android非同期設計の地雷

はじめに

Android 1.5の頃からアプリを作っていると、非同期APIは何度も主役交代してきました。AsyncTask、Loader、Rx、Coroutines。道具は進化しましたが、障害対応の現場で見る事故の根本原因は驚くほど似ています。

本記事では、各時代で実際に踏みがちな地雷を振り返りながら、2026年時点でも有効だった実務ルールに絞って整理します。ポイントは「どのAPIを使うか」より「キャンセル・責務・エラーハンドリングをどう設計するか」です。

AsyncTask時代の地雷

AsyncTaskの時代は、とにかく画面回転とライフサイクルの相性で苦しみました。最も多かったのは、非同期処理中に画面が破棄され、結果をUIへ反映しようとしてクラッシュする問題です。

典型的な事故

  • Activity参照を内部クラスで握り続ける
  • 画面回転後に古いインスタンスへコールバックしてアプリがクラッシュ
  • キャンセルを呼んでも中断されず、二重更新が起きる

学んだこと

「処理がバックグラウンドで動ける」ことと「UIを安全に変更できる」ことは別問題です。UIのライフサイクルとの接続点を設計しない限り、どんな非同期APIでも事故は起きます。

Loader時代の地雷

Loaderはライフサイクル連携を前進させましたが、今度は責務の分散が問題になりました。データ取得ロジックがFragmentやActivityに寄りすぎると、見通しが急激に悪化します。

典型的な事故

  • LoaderCallbacksに業務ロジックが混ざり、テストが難しい
  • 画面ごとに似たLoader実装が増殖し、修正漏れが発生
  • キャッシュ戦略が画面単位でバラバラになる

学んだこと

ライフサイクルに強い仕組みだけでは足りません。責務をUI層から分離し、ユースケース単位で再利用できる構造が必要です。

ReactiveX時代の地雷

ReactiveX(Rx)は表現力が高く、複雑な非同期フローを綺麗に書けました。ただし、チームで運用するとDispose漏れとScheduler設計のばらつきが頻発しました。

典型的な事故

  • subscribe() が散在して購読ライフサイクルを追えない
  • CompositeDisposable の解放漏れで画面離脱後も処理継続
  • observeOn / subscribeOn の設計が統一されずデバッグ困難

学んだこと

Rxの難しさは演算子ではなく運用ルールです。購読開始・終了の責務を定型化しないと、実装者依存の品質になります。

Coroutines時代の地雷

Coroutinesは読みやすくなりましたが、地雷が消えたわけではありません。特に初期導入時は「軽く書ける」ことが裏目に出ます。

典型的な事故

  • GlobalScope の使用でライフサイクル外に処理が残る
  • launchasync を混在させ、例外伝播が意図通りにならない
  • withContext の乱用で責務境界が曖昧になる

学んだこと

Coroutinesは「正しくキャンセルが伝播する設計」を作って初めて安全になります。書きやすさは設計品質の代替にはなりません。

非同期処理の難しさ

どのような形で非同期処理をするにせよ、以下のことが地雷の要因になります。

  1. 非同期処理のキャンセルタイミングについてきちんとした考慮がされていない
  2. UI層とデータ層の非同期責務が混ざっている
  3. エラー分類とリトライ方針がユースケースごとに不統一

この3つを放置すると、どのAPIでも「たまに落ちる」「再現しづらい」不具合の原因になります。

まとめ

非同期APIは進化し続けていますが、地雷の本体は道具ではなく設計です。私が長年の移行で得た結論は次の3点です。

  1. 非同期処理のキャンセル戦略を決める
  2. UI層から非同期責務を剥がし、境界を固定する
  3. スレッド境界とオブジェクトの参照関係を意識する

「新しいAPIに移行したのに不具合が減らない」と感じるチームでは、非同期処理の設計を見直すことが大切です。

🤘

メタルで聴く

この記事をメタルサウンドで
Threads of Ruin, Signals of Dawn
Progressive Metal
AsyncTask, Loader, Rx, Coroutinesと複数世代の非同期モデルを横断し、設計原則を再構成していく記事構成が、多層的で構築的なProgressive Metalの性質と一致するため。
🎵 Lyrics
古いスレッドの残響が 夜に刺さる 画面は消えても 処理はまだ走る シグナルは絡み 例外は笑う それでも設計は 朝へ向かう キャンセルを語れ 依存を分けろ 速さより先に 壊れ方を決めろ 時代は変わる 罠は姿を変える 原則だけが 最後に残る