Jetpack Compose 可组合项生命周期及其常见处理Effect副作用API_jetpack compose return@(3)

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

点击Button后,启动协程,在协程中延迟3s重组并刷新Text文案。

DisposableEffect
@Composable
@NonRestartableComposable
fun DisposableEffect(
    key1: Any?,
    effect: DisposableEffectScope.() -> DisposableEffectResult
) {
    remember(key1) { DisposableEffectImpl(effect) }
}

对于需要在键发生变化或可组合项退出组合后进行清理的副作用,可以使用 DisposableEffect。如果 DisposableEffect 中的key发生变化,那么就会执行onDispose()资源释放等操作,并重新执行DisposableEffect。

DisposableEffect中强制以onDispose进行收尾,不加就会编译报错。因此DisposableEffect适合有资源需要收尾的场景下。

使用示例:

@Composable
fun HomeScreen(
    lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
    onStart: () -> Unit, // Send the 'started' analytics event
    onStop: () -> Unit // Send the 'stopped' analytics event
) {
    // Safely update the current lambdas when a new one is provided
    val currentOnStart by rememberUpdatedState(onStart)
    val currentOnStop by rememberUpdatedState(onStop)

    // If `lifecycleOwner` changes, dispose and reset the effect
    DisposableEffect(lifecycleOwner) {
        // Create an observer that triggers our remembered callbacks
        // for sending analytics events
        val observer = LifecycleEventObserver { _, event ->
            if (event == Lifecycle.Event.ON_START) {
                currentOnStart()
            } else if (event == Lifecycle.Event.ON_STOP) {
                currentOnStop()
            }
        }

        // Add the observer to the lifecycle
        lifecycleOwner.lifecycle.addObserver(observer)

        // When the effect leaves the Composition, remove the observer
        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
        }
    }

    /* Home screen content */
}

LaunchedEffect 内部开启了协程,并在退出组合时取消协程,DisposableEffect + rememberCoroutineScope 的方式可以模拟 LaunchedEffect,如下:

//LaunchedEffect
LaunchedEffect(key1 = Unit) {
}

//DisposableEffect + rememberCoroutineScope
val scope = rememberCoroutineScope()
DisposableEffect(key1 = Unit) {
    val job = scope.launch { }
    onDispose {
        job.cancel()
    }
}

rememberUpdatedState

LaunchedEffect(key) 会在key发生变化时会重启协程,如果不希望key变化时协程中断而是继续执行,可以通过 rememberUpdatedState 获取最新状态即可。

@Composable
fun <T> rememberUpdatedState(newValue: T): State<T> = remember {
    mutableStateOf(newValue)
}.apply { value = newValue }

//MutableState
@Stable
interface MutableState<T> : State<T> {
    override var value: T //rememberUpdatedState每次重组时都会对该值进行更新
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}

rememberUpdatedState 源码很简单,内部通过 remember + mutableStateOf 的方式,保证每次重组时都会将newValue 值进行更新到MutableState.value中,最终副作用里访问的也是最新的newValue了,从而实现副作用在不中断的前提下访问到最新传入的值。使用示例如下:

@Composable
fun LandingScreen(onTimeout: () -> Unit) {

    // LandingScreen重组时会引用到最新的onTimeout函数
    val currentOnTimeout by rememberUpdatedState(onTimeout)

    // 如果发生重组,delay函数不会再次执行了;而currentOnTimeout却是最新的onTimeout函数。
    LaunchedEffect(true) {
        delay(SplashWaitTimeMillis)
        currentOnTimeout()
    }

    /* Landing screen content */
}

SideEffect

SideEffect 在每次成功重组时都会执行,这么看好像SideEffect 并不能处理什么副作用呀。其实还是有点区别的,SideEffect只会在重组成功之后才会执行,如果重组失败,那么SideEffect中的lambda将不再执行,以免在当前组合操作失败时使对象处于不一致状态。

使用示例:

@Composable
fun SideEffectStudy() {
    Log.e("Tag", "SideEffect launch")
    throw IllegalArgumentException("exception throw")
}

上述可组合项执行时会抛出异常,在抛异常之前会先输出Log。如果我们想重组成功之后再输出Log该怎么办呢?这时候就可以使用SideEffect了:

@Composable
fun SideEffectStudy() {
    SideEffect {
        Log.e("Tag", "SideEffect launch")
    }
    throw IllegalArgumentException("exception throw")
}

可以看到将Log日志放到了SideEffect内部,这样就可以保证只有成功重组后才会执行SideEffec t内部的lambda。

总结
  • LaunchedEffect 内部会启动协程,所以适合当副作用中有耗时任务时的场景下;
  • rememberCoroutineScope当需要在可组合项外启动协程时(如onClick中),可以使用rememberCoroutineScope
  • DisposableEffect 适合有资源需要收尾的场景下,内部一定要重写onDispose(),用于释放资源、解注册等操作;
  • rememberUpdatedState 对于包含长期操作的副作用很有效,尤其适合用在重启这些操作时代价高昂的场景中;
  • SideEffect 每次重组时都会执行内部的lambda,不过SideEffect 能确保可组合项成功重组之后才会执行内部的 Lambda。

这篇文章主要讲了Compose是什么以及我们要开始学习它的必要性。最后为了帮助大家更好的熟知 Jetpack Compose 这一套体系的知识点,这里记录比较全比较细致的《Jetpack 入门到精通》(内含Compose) 学习笔记!!! 对Jetpose Compose这块感兴趣的小伙伴可以参考学习下……

Jetpack 全家桶(Compose)

Jetpack 部分

  1. Jetpack之Lifecycle
  2. Jetpack之ViewModel
  3. Jetpack之DataBinding
  4. Jetpack之Navigation
  5. Jetpack之LiveData

Compose 部分
1.Jetpack Compose入门详解
2.Compose学习笔记
3.Compose 动画使用详解

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值