Android Compose LaunchedEffect ,DisposableEffect,SideEffect
Compose里面附带效应是指对应用的其余部分可见的任何更改。
LaunchedEffect
LaunchedEffect可以在某一个可组项中运行挂起函数。退出组合时协程取消。
fun LaunchedEffect(
key1: Any?,
block: suspend CoroutineScope.() -> Unit
) {
val applyContext = currentComposer.applyCoroutineContext
remember(key1) { LaunchedEffectImpl(applyContext, block) }
}
block就是要执行的挂起函数,key1可以为任何值,这里分几种:
- state变量,如果key1为state变量,那么当state的值改变时LaunchedEffect将取消当前协程并重新启动新的协程执行挂起函数。
- key1为Unit或者true时,这个时候LaunchedEffect和当前重组函数保持一致的生命周期。
- 普通变量:普通变量值的变化也不会引起当前协程的取消。
LaunchedEffect是只能在可组合函数内使用,如果想在可组合函数外使用,并且生命周期还需要和可组合函数相同,那么这个时候可以使用rememberCoroutineScope,看下面一个简单的例子
val scope = rememberCoroutineScope()
Button(onClick = { scope.launch { Log.i("test","I will do some important job here") } }) {
}
在onClick中要执行耗时的操作,这个时候就可以使用rememberCoroutineScope。
DisposableEffect
LaunchedEffect只是在state发生改变的时候才会取消协程启动新的协程,需要每次重组的时候都需要做清理工作那就可以使用DisposableEffect。看下面的例子:
var count by remember {
mutableStateOf(0)
}
DisposableEffect(count){
if(count < 100){
count++
}
onDispose {
count =0
}
}
使用DisposableEffect必须需要实现onDispose,即在退出的时候做清理工作,需要注意的是DisposableEffect不能执行挂起函数。如果需要执行挂起函数那就使用上面的:rememberCoroutineScope。
SideEffect
对于SideEffect官网给的作用是:将 Compose 状态发布为非 Compose 代码。这个应该怎么理解呢?我们来看一个例子:
@Composable
fun userName(brand:String):Car{
val car = remember {
Car(Color.BLUE,"BMW")
}
SideEffect {
car.brand = brand
}
return car
}
car是一个remember对象,我们在这里把它进行了返回,传给非composable函数使用。SideEffect会在每次重组的时候都发生改变,所以共享了同一个值。