Kotlin

Kotlin Coroutines 入門チュートリアル:ViewModel と Retrofit の実装ガイド

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


スポンサードリンク

Kotlin Coroutines の基礎と Kotlin 1.9 / 2.0 での主な変更点

本稿は Android 開発者を対象に、Coroutines の基本概念Kotlin 1.9/Kotlin 2.0(プレビュー) における実装上のポイントを公式情報に基づいて解説します。
参考リンクはすべて公式ドキュメント・ブログ記事です。


suspend 関数と CoroutineScope の本質

要素 説明
suspend 関数呼び出しを中断(await)できることをコンパイラに指示します。実行時には Continuation<T> が生成され、現在のコルーチンコンテキストが保存されます。この仕組みのおかげでスレッドをブロックせずに非同期処理を書けます。
CoroutineScope コルーチンの ライフサイクルコンテキスト(Dispatcher・Job など) を保持します。scope.launch { … } のようにスコープを明示することで、キャンセルや例外伝搬が一元管理できます。

実装例

withContext により、IO スレッドプールでネットワーク呼び出しを行い、結果は元のコンテキスト(通常は Main)に戻ります。

参考: Kotlin Coroutines Guide – suspend functions


Job と Structured Concurrency の役割

用語 意味
Job コルーチンの実行単位。cancel() で子コルーチンへキャンセルが伝搬します。
Structured Concurrency 親スコープが終了したら必ず子ジョブも終了させる設計原則。Android の画面遷移や ViewModel の破棄に対して安全なリソース管理を実現します。

Kotlin 1.9 での変更点(正確な表現)

  • runBlocking常にキャンセル可能 でしたが、Kotlin 1.9 ではテスト向け API が統一され、runTest { … } に置き換えられました。runBlocking 自体の挙動は変わっていません(※公式リリースノート参照)。

参考: Kotlin 1.9 Release Notes – Coroutines

実装例

SupervisorJob により、子コルーチンの例外が他の子に影響しません。


launch と async の使い分け

API 戻り値 主な用途
launch Job 副作用だけを行う(UI 更新、ログ出力、データ保存など)
async Deferredawait() で取得 計算結果や外部 API のレスポンスなど 戻り値が必要 なケース

launch の例

戻り値を待たないので、処理が完了したかどうかを個別にチェックする必要はありません。

async / await の例(例外伝搬も同時にハンドリング)

await() 時に例外が再スローされるため、上位の try/catch で一括処理できます。

参考: Structured concurrency – launch vs async


Dispatchers と withContext の選択基準

Dispatcher 主な用途
Dispatchers.Main UI スレッド上での描画・LiveData 更新など。AndroidX lifecycle-runtime-ktx が提供する Main dispatcher を使用します。
Dispatchers.IO ファイル I/O、データベースアクセス、ネットワーク呼び出しなどブロッキング系処理に最適化されたスレッドプールです。
Dispatchers.Default CPU 集中型(画像加工、暗号化、複雑な計算)に対してコア数に合わせた固定サイズプールを提供します。

正しい情報への訂正

  • Kotlin 2.0 ベータで Dispatchers.IO が WorkManager と連携するオプションが追加 という記述は事実ではありません。現在(2024‑12 時点)でも Dispatchers.IO は純粋なスレッドプールであり、WorkManager との自動統合機能は提供されていません。
  • WorkManager と Coroutines を組み合わせる場合は、CoroutineWorkerdoWork() 内で withContext(Dispatchers.IO) 等を使用します(公式ブログ参照)。

参考: Kotlin 2.0 Preview – Coroutines
参考: WorkManager + Coroutines – official guide

withContext を使ったスレッド切り替え例

ベストプラクティスまとめ

  1. UI だけ を扱うなら Dispatchers.Main(デフォルト)。
  2. ブロッキング I/O は必ず withContext(Dispatchers.IO) に包む。
  3. CPU 重い計算Dispatchers.Default へ委譲する。
  4. スコープ全体を変更しない ように、局所的な切り替えは常に withContext を使用する。

ViewModel・lifecycleScope で安全に UI スレッド操作

viewModelScope の特徴

  • AndroidX Lifecycle が提供する viewModelScopeViewModel のライフサイクル にバインドされた CoroutineScope
  • Activity/Fragment が破棄されても ViewModel が残るケース(例: 画面回転)で、ジョブは自動的にキャンセルされます。

実装例

viewModelScope.launch が自動的に Dispatchers.Main.immediate を使用し、UI 更新は安全です。

Retrofit の suspend 関数とエラーハンドリング

suspend 関数は内部で Call.await() と同等の処理を行い、例外は通常の try/catch で捕捉できます。

参考: Retrofit + Coroutines – official guide


キャンセル・タイムアウト・テスト戦略

キャンセルと timeout 系 API

関数 動作
Job.cancel() 子ジョブへキャンセルが伝搬し、CancellationException が投げられる。
withTimeout(ms) 指定時間内に完了しなければ TimeoutCancellationException をスローして処理を中断。
withTimeoutOrNull(ms) タイムアウト時に null を返すので例外処理が不要になるケースで便利。

Kotlin 1.9 の最適化

  • withTimeoutOrNullwithTimeout は内部実装が軽量化され、キャンセルコストが低減されています(公式リリースノート参照)。

コルーチンテストのベストプラクティス

  1. runTestkotlinx-coroutines-test)を使い、仮想時間で delay, withTimeout などを高速に検証。
  2. Turbineapp.cash.turbine)は Flow のシーケンステストを直感的に記述でき、awaitItem() / ensureAllEventsConsumed() が利用可能。

実装例(JUnit5 + runTest)

Flow のテスト例(Turbine)

参考:
kotlinx.coroutines.test – runTest
Turbine – Flow testing library


Kotlin 2.0(プレビュー)での注目変更点とベストプラクティス

変更点 内容・影響
Structured Concurrency の強化 スコープ外から cancel() が呼ばれた場合でも、子ジョブが必ずキャンセルされるように内部チェックが追加されました。これにより「スコープ漏れ」バグの検出が容易になります(Kotlin 2.0 blog)。
CancellationException の階層化 CancellationExceptionTimeoutCancellationException から派生し、isActive チェックが高速化されました。開発者側でのコード変更は不要です。
runTest の統合 従来の runBlockingTestrunTest が一本化され、テスト時に自動的にディスパッチャーを切り替える仕組みがシンプルになりました(Release notes)。
新しい SupervisorScope のデフォルト挙動 supervisorScope { … } 内の子コルーチンは例外が起きても他の子に影響しません。これが「UI だけ失敗してもバックグラウンド処理を続行」したいシナリオで便利です。

推奨パターン(Kotlin 2.0 プレビュー対応)

supervisorScopeSupervisorJob の組み合わせで、部分的な失敗 が全体のキャンセルにつながらない安全設計が実現できます。


まとめ:安定した Coroutines 実装に向けて

  1. Dispatcher は用途別に明示的に選択し、withContext で局所的に切り替える。
  2. Structured Concurrency と Job の階層管理を徹底し、ViewModel・lifecycleScope にバインドしたスコープだけを使用する。
  3. launch は副作用、async は結果取得と例外伝搬に使い分ける。
  4. キャンセルとタイムアウトは必ず組み込むことでリソースリークを防止。
  5. テストは runTest + Turbine で決め打ちし、仮想時間による高速かつ決定的な検証を行う。
  6. Kotlin 2.0(プレビュー)では Structured Concurrency の強化テスト API 統合が最大のメリットになるため、コードベースに早めに取り込むことを推奨する。

以上が Android 開発者向けに整理した Coroutines の基礎と、Kotlin 1.9/2.0 における最新情報です。実装時は必ず公式リファレンスを参照し、バージョンアップに伴う挙動変更を確認してください。


参考リンク(すべて公式)

内容 URL
Kotlin Coroutines 基本ガイド https://kotlinlang.org/docs/coroutine-guide.html
AndroidX Lifecycle / viewModelScope https://developer.android.com/topic/libraries/architecture/viewmodel#viewmodelscope
Retrofit + Coroutines 公式ドキュメント https://developer.android.com/kotlin/coroutines#retrofit
kotlinx.coroutines.test(runTest) https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/
Turbine – Flow テストライブラリ https://github.com/cashapp/turbine
Kotlin 1.9 Release Notes – Coroutines https://kotlinlang.org/docs/whatsnew19.html#coroutine-improvements
Kotlin 2.0 Preview – Coroutines Improvements (JetBrains Blog) https://blog.jetbrains.com/kotlin/2024/10/kotlin-2-preview-coroutine-improvements/
WorkManager と Coroutines の公式ガイド https://developer.android.com/topic/libraries/architecture/workmanager/coroutines

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-Kotlin