LaunchedEffect: Use coroutines in Jetpack Compose

Insert picture description here

LaunchedEffect


LaunchEffect allows us to use coroutines in Composable

@Composable fun DisposableEffect(
    vararg keys: Any?, 
    effect: DisposableEffectScope.() -> DisposableEffectResult
): Unit
  • Like the DisposableEffectsame, Composableexecute block when entering composition
  • When Composable is detached from the tree, CoroutineScope executes cancel
  • If the parameter keys change, it will be executed cancelagain after executioneffect

In short, it supports the execution of Coroutine's DisposableEffect, which will automatically execute cancel without manualonDispose


Instructions


The usage is as follows:

@Composable
fun SplashScreen(
    onTimeOut: () -> Unit
) {
    
    
    LaunchedEffect(Unit) {
    
     
        delay(SplashWaitTime)
        onTimeOut()
    }
    ...
}

For example, above, the screen opening page is displayed at the first startup. Parameter Unit, because there will be no diff, the life cycle effect of onActive is realized, that is, it is executed once at the first composition

@Composable
fun SearchScreen() {
    
    
    ...
    var searchQuery by remember {
    
     mutableStateOf("") }
    LaunchedEffect(searchQuery) {
    
    
        // execute search and receive result
    }
    ...
}

As above, when the search term changes, the search is initiated.

The important significance of letting Composable support coroutines is that some simple business logic can be directly encapsulated and reused in the form of Composable without the need for additional ViewModel.


Realization principle


@Composable
@ComposableContract(restartable = false)
fun LaunchedEffect(
    subject: Any?,
    block: suspend CoroutineScope.() -> Unit
) {
    
    
    val applyContext = currentComposer.applyCoroutineContext
    remember(subject) {
    
     LaunchedEffectImpl(applyContext, block) }
}

The implementation is very simple, use the remembersaved subject parameter, and then LaunchedEffectImplstart the coroutine

internal class LaunchedEffectImpl(
    parentCoroutineContext: CoroutineContext,
    private val task: suspend CoroutineScope.() -> Unit
) : CompositionLifecycleObserver {
    
    

    private val scope = CoroutineScope(parentCoroutineContext)
    private var job: Job? = null

    override fun onEnter() {
    
    
        job?.cancel("Old job was still running!")
        job = scope.launch(block = task)
    }

    override fun onLeave() {
    
    
        job?.cancel()
        job = null
    }
}

LaunchedEffectImplIt can be provided CoroutineScope, with the help of the CompositionLifecycleObserverprovided life cycle, the launchcoroutine is started when entering the screen, and the coroutine is cancelcancelled when leaving the screen .

Guess you like

Origin blog.csdn.net/vitaviva/article/details/114503797