LoginSignup
2
1

(備忘)rememberCoroutineScope,LaunchEffect,launchそれぞれの違いについて

Last updated at Posted at 2024-03-19

Jetpack Composeでは、非同期処理を行うために主に以下の3つの方法が使われます: rememberCoroutineScopeLaunchedEffect、そしてCoroutineScope.launchによる通常のlaunchです。

rememberCoroutineScope

  • rememberCoroutineScopeは、Composable関数内で使用可能なCoroutineScopeを返します。これを使うと、そのComposable関数と同じライフサイクルを共有するコルーチンを起動できます。

  • この方法はよくイベントハンドラ内で使われ、例えばユーザーがボタンをクリックした時にバックグラウンド処理を開始したい場合に便利です。

  • rememberCoroutineScopeによって提供されるCoroutineScopeは、Composableが存在する間生存し続け、Composableが再構築されてもキャンセルされません。

val scope = rememberCoroutineScope()

Button(onClick = {
    scope.launch {
        // 非同期処理
    }
})

LaunchedEffect

  • LaunchedEffectは、特定のキーが変更された時に実行される副作用(サイドエフェクト)をComposable関数内で起動します。キーが変わらなければ副作用は維持されますが、キーが変わると副作用はキャンセルされて新たに起動されます。

  • LaunchedEffectはComposable関数のライフサイクルに密接に結びついており、Composableが画面から取り除かれると自動的にキャンセルされます。

  • これは初期化処理やデータの読み込みなど、一度だけ実行したい非同期処理に使用されます。

LaunchedEffect(Unit) {
    // 一度だけ実行する非同期処理
}

例
以下のcounterの値が変わるたびにLandingScreen内のonTimeoutの内容が"Even"や"Odd"に更新され
3秒のDelayが終わったタイミングで最新のonTimeoutが実行される

@Composable
fun ParentScreen() {
    var counter by remember { mutableStateOf(0) }

    Button(onClick = { counter++ }) {
        Text("Increment")
    }

    val onTimeout = {
        if (counter % 2 == 0) {
            println("Even")
        } else {
            println("Odd")
        }
    }

    LandingScreen(onTimeout = onTimeout)
}

@Composable
fun LandingScreen(onTimeout: () -> Unit) {
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        // このLaunchedEffectは、onTimeoutの参照が変わるたびに再起動します。
        LaunchedEffect(onTimeout) {
            delay(3000) // 3秒のディレイ
            onTimeout()
        }
    }
}

CoroutineScope.launch

  • launchコルーチンを開始するためにCoroutineScope内で直接呼び出されます。これは通常、ViewModelActivityFragmentなど、ライフサイクルを持つコンポーネント内で使用されます。

  • コルーチンのライフサイクルはCoroutineScopeによって管理され、このスコープは通常、viewModelScopeやライフサイクルスコープ(lifecycleScope)などに基づいています。

  • これは、ViewModelでのデータの読み込みや長期実行タスクなど、UIのライフサイクルとは独立して非同期処理を行いたい場合に適しています

viewModelScope.launch {
    // 長期間実行する非同期処理
}

まとめ

これら3つの方法は、それぞれ異なるシナリオとライフサイクル管理の要件に基づいて非同期処理を実行するためのものです。

  • rememberCoroutineScopeイベントに基づく動的な起動に使用
  • LaunchedEffectComposableのライフサイクルに密接に結びついた副作用に使用
  • そしてlaunchViewModelやActivityといったコンポーネントのライフサイクルが管理する長期間実行する非同期処理に使用されます。
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1