Coroutine Builder — Kotlin Coroutinesの関数で、コルーチンを作成・起動し、その実行方法を定義します。launch、async、runBlocking、produceの各ビルダーは、バックグラウンドタスクから結果を返す並列計算まで、さまざまなシナリオをカバーします。JetBrains, 2024によると、Coroutine Builderはコルーチンモデルの基盤であり、構造化された並行処理とライフサイクル管理を提供します。
重要なポイント
Coroutine Builderは、CoroutineScopeとsuspendブロックを受け取り、新しいコルーチンを作成して起動するKotlinの拡張関数です。各ビルダーは、結果の有無、スレッドブロッキングの有無、非同期実行など、コルーチンの実行方法を定義します。ビルダーは言語のコルーチンモデルへのエントリーポイントです。
すべてのビルダーはCoroutineScopeを介して動作し、子コルーチンのライフサイクルを管理します。スコープがキャンセルされると、そのスコープを介して起動されたすべてのコルーチンが自動的にキャンセルされます — これが構造化された並行処理の原則です。このアプローチにより、コルーチンのリークを防ぎ、予測可能な終了を保証します。
import kotlinx.coroutines.*
fun main() = runBlocking {
// ビルダーはCoroutineScope内で実行されます
val job = launch {
delay(1000L)
println("世界!")
}
println("こんにちは、")
job.join()
}
Kotlinには4つの組み込みコルーチンビルダーがあります: launch、async、runBlocking、produce。それぞれに独自の戻り値の型と適用領域があります。Androidモバイル開発では、launchとasyncが主要なビルダーで、ノンブロッキングで動作し、アーキテクチャコンポーネントと統合できます。
| ビルダー | 戻り値の型 | スレッドブロッキング | シナリオ |
|---|---|---|---|
| launch | Job | なし | Fire-and-forgetタスク |
| async | Deferred<T> | なし | 並列計算 |
| runBlocking | T | あり | テスト、main関数 |
| produce | ReceiveChannel<E> | なし | ストリーミング(非推奨) |
各ビルダーは追加パラメーターを受け付けます: CoroutineStart(起動戦略)、CoroutineContext(ディスパッチャー、例外)、名前付きコードブロック。デフォルトでは、コルーチンは即座に開始されます(CoroutineStart.DEFAULT)。
launchはAndroid開発で最も使用されるビルダーです。結果を返さないコルーチンを起動し、そのライフサイクルを管理するためのJobオブジェクトを返します。データベースへの保存、アナリティクスの送信、UIの更新など、副作用のみが必要な操作に最適です。
launchビルダーはCoroutineScope、オプションのCoroutineContext、およびsuspendブロックを受け取ります。返されるJobを使用すると、コルーチンのキャンセル、完了の待機、ステータスの確認ができます。
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
val data = fetchFromNetwork()
saveToDatabase(data)
}
job.start()
job.join()
CoroutineStart.LAZYパラメーターは、start()またはjoin()が明示的に呼び出されるまで実行を延期します。これは遅延初期化や条件付き実行に便利です。標準の即時実行にはCoroutineStart.DEFAULTを使用するか、パラメーターを省略します。
asyncはDeferred<T> — 結果の非同期プロミスを返すビルダーです。await()を呼び出すと、スレッドをブロックせずに結果が得られるまでコルーチンを一時停止します。これはKotlinコルーチンにおける並列タスクの主要なメカニズムです。
asyncは、複数の独立した操作を同時に実行する必要がある場合に特に効果的です。suspend関数の逐次呼び出しとは異なり、asyncはコルーチンを並列に起動し、総実行時間を短縮します。
suspend fun fetchUserData(): UserData {
val deferred1 = CoroutineScope(Dispatchers.IO).async { api.getProfile() }
val deferred2 = CoroutineScope(Dispatchers.IO).async { api.getSettings() }
val deferred3 = CoroutineScope(Dispatchers.IO).async { api.getNotifications() }
return UserData(
profile = deferred1.await(),
settings = deferred2.await(),
notifications = deferred3.await()
)
}
DeferredはJobを継承しているため、asyncはキャンセル、完了待機、例外処理などすべてのライフサイクル操作をサポートします。スコープがキャンセルされると、子Deferredコルーチンは自動的にキャンセルされます。
runBlockingは、コルーチンが完了するまで現在のスレッドをブロックする唯一のビルダーです。新しいCoroutineScopeを作成し、渡されたコルーチンを起動して、呼び出しスレッドをブロックします。main()エントリーポイント、テスト、blockingコードとの統合時に使用されます。
runBlockingは3つのシナリオで正当化されます: アプリケーションのエントリーポイント(main)、suspend関数の単体テスト、suspendが使用できないコールバックベースのライブラリとの統合。本番Androidコードでは、メインスレッドでのrunBlockingの使用は強く推奨されません。
class CoroutineTest {
@Test
fun `test suspend function`() = runBlocking {
val result = mySuspendFunction()
assertEquals("expected", result)
}
}
テストでは、runBlockingの代わりにTestCoroutineDispatcherを備えたkotlinx-coroutines-testを使用することをお勧めします。これにより時間制御が可能になり、テスト環境でのブロッキングを回避できます。
Coroutine Builderの選択は、戻り値と実行シナリオによって異なります。データを返す必要がない操作にはlaunchを使用します。非同期操作の結果が必要な場合はasyncを使用します。runBlockingは橋渡しのみに使用し、リアクティブストリームにはproduceをFlowに置き換えてください。
Kotlin Coroutinesを使用するAndroidプロジェクトでは、launchとasyncが主要なビルダーのペアです。launchはViewModelやUseCasesでコルーチンを起動するために使用され、asyncはネットワークやデータベースへの並列リクエストに使用されます。最新のライブラリ(Ktor、Room)はすでにsuspend関数をサポートしており、asyncの直接使用の必要性を最小限に抑えます。
よくある質問
launchはJobを返し、実行結果を返しません。一方、asyncはDeferred<T>を返し、await()で結果を取得できます。launchはfire-and-forget操作に、asyncはデータを返すタスクに使用されます。
推奨されません。メインスレッドでのrunBlockingはANRを引き起こし、UIをブロックします。ActivityやFragment内ではlifecycleScope.launchを使用してください — ブロッキングなしの組み込みソリューションです。
launchビルダーはJobオブジェクトを返し、コルーチンのライフサイクル制御(cancel、join、isActive、isCompleted、isCancelled)を可能にします。
Deferred<T>は結果の非同期プロミスで、asyncビルダーによって返されます。Jobを継承し、結果取得用のawait()、ノンブロッキングアクセス用のgetCompleted()、例外確認用のgetCompletionExceptionOrNull()メソッドを追加します。
CoroutineStart.LAZYパラメーターを使用します: scope.launch(start = CoroutineStart.LAZY) { ... }。その後、job.start()またはjob.join()を呼び出して実際に実行します。これは遅延初期化や条件付きコルーチン実行に便利です。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。