Compose中的一些机制验证与总结——remember

2024-01-13 18:36

本文主要是介绍Compose中的一些机制验证与总结——remember,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在搞一个基于 Compose 实现的低代码跨平台项目,涉及到一些 Compose 运行时的一些机制问题,周末写了个 demo 验证总结一下,总体是与过往经验相符的,也发现了一些小的细节是以前不太清楚的,可以一起学习研究一下,如有错误欢迎指正!

remember 简介

先贴一段 GPT4 给的简介:

remember 是 Jetpack Compose 中的一个核心函数,它用于记住那些你不希望在重组(recomposition)时重新创建的数据。举个例子,这可能是一种状态、一个对象实例或一个计算成本较高的结果。它有助于保持性能并避免不必要的计算。

使用示例

先看测试代码:

@Composable
fun ContentView(index: Int) {val item = remember {mutableStateOf(DataA()).also {Log.d("Test", "ContentView in remember, item=$it")}}Column(modifier = Modifier.fillMaxSize().border(3.dp, Color.Cyan)) {Text(text = "this is page $index,\n item= $item")}
}class DataA(val id: Int = 0,val name: String = ""
)

上面的代码中,我们定义了一个 ContentView 内容页,外面传进来一个 index,在 ContentView 组件内,我们用 remember 来包一个state变量,remember 里面打印一行日志方便观察 remember 内部的执行情况,页面就只显示"this is page $index,\n item= $item",打印出当前页面的 index 和 remember 的 item 对象,非常简单

接下来看我们怎么使用它:

常规使用

@Composable
fun TestCompose2() {var index by remember {mutableIntStateOf(0)}Column {Row {repeat(3) { repeatIndex ->TabBtn(repeatIndex) { tabIndex ->index = tabIndexLog.v("Test", "onClicked: tab_$tabIndex")}}}ContentView(index = index)}
}@Composable
fun TabBtn(index: Int, onClicked: (Int) -> Unit) {OutlinedButton(onClick = { onClicked(index) }) {Text(text = "Tab $index")}
}

写过 compose 的同学应该脑海中已经有画面了对吧,没错,跑起来是这样的:
在这里插入图片描述

查看日志,remember 里面的日志也打印了
在这里插入图片描述

然后点击上面的 tab1,使页面切换:
在这里插入图片描述
在这里插入图片描述

我们发现页面切换之后,page 更新为 0 了,但是 item 对象还是没有变,而且remember 里面的那行日志也不会再次打印。

因为其实我们这样并不是真正的切换了 ContentView,ContentView 还是那个 ContentView,只是我们给他传的参数变了,使它发生重组(界面刷新)而已,而 remember 的作用正是处理这种重组的情况的

对比不使用remember的情况

而如果我们不使用 remeber ,将 ContentView 里的 item 那段改为如下:

	val item = run {mutableStateOf(DataA()).also {Log.d("Test", "ContentView in run, item=$it")}}

那么每次点击 tab 切换的时候,ContentView 发生重组,都会执行一遍这里的逻辑
在这里插入图片描述
所以这里每次都不一样了,即使切回到 tab0 之后,也不再是之前那个 item,所以这就是使用和不使用 remember 的区别

remember 无法处理的情况

如果我们稍微改一下用 ContentView 的方式,如下末尾 3 行代码:

@Composable
fun TestCompose2() {var index by remember {mutableIntStateOf(0)}Column {Row {repeat(3) { repeatIndex ->TabBtn(repeatIndex) { tabIndex ->index = tabIndexLog.v("Test", "onClicked: tab_$tabIndex")}}}when (index) {0 -> ContentView(index = 0)1 -> ContentView(index = 1)else -> ContentView(index = 2)}}
}

此时即使 ContentView 里用的时 remember,每次打印出的 item 对象也已经是新的对象了。如下:
在这里插入图片描述
这是因为此时切换 tab 之后实现了真正的切换不同的 ContentView,旧的 ContentView 被移出了可组合范围,下一次再回来的时候就会重新执行一遍 remember 内的逻辑。换句话说,remember 只能在函数存在于组合树且未被移除时保持其状态。

总结:

  1. remember 用于保存数据,这些数据只应该在 Compose 函数的重组过程中保持不变,但不跨过函数的移除和添加
  2. 使用 remember 保存的对象当 Compose 函数被移出组合树后不会保留。
  3. 当 Compose 函数再次被组合进入时,remember 将重新获得一个新的对象。
  4. 要跨组合保持对象,应使用外部状态管理,如 ViewModel。

这篇关于Compose中的一些机制验证与总结——remember的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/602411

相关文章

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

深入理解go中interface机制

《深入理解go中interface机制》本文主要介绍了深入理解go中interface机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前言interface使用类型判断总结前言go的interface是一组method的集合,不

C# async await 异步编程实现机制详解

《C#asyncawait异步编程实现机制详解》async/await是C#5.0引入的语法糖,它基于**状态机(StateMachine)**模式实现,将异步方法转换为编译器生成的状态机类,本... 目录一、async/await 异步编程实现机制1.1 核心概念1.2 编译器转换过程1.3 关键组件解析

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理