当前位置: 首页 > news >正文

remember()、rememberSaveable()和rememberSaveableStateHolder()

从字面上理解,这三个函数都是对Composable重组时的数据做记忆保存的,但是它们也有一些区别。

1.remember

remember: 它的作用是在重组 (Recomposition) 期间保持状态。
但如果Composable从组件树中被移除(例如,导航到新页面),或者发生配置变更(如屏幕旋转)导致Activity重建,它的状态就会丢失。
remember可以带多个参数一个lambda,形式为remember(key1,key2...){ ...... },在第一次的时候会执行lambda,后面需要key改变的时候,才会执行lambda。
我们常见的remember{......},可以理解为key始终不变的情况,也就是只在第一次重组的时候执行一次,后面不会再执行。

2.rememberSaveable

rememberSaveable是remember的增强版,不仅能在重组期间保持状态,还能在配置变更甚至进程死亡后存活下来。它通过将状态保存到Bundle中来实现这一点。
但是,rememberSaveable有一个前提:它所包裹的Composable必须持续存在于组件树中。一旦Composable被移除,其状态也会被丢弃。

这时,rememberSaveableStateHolder就派上了用场。它解决了当Composable暂时离开组件树时,如何保留其rememberSaveable状态的问题。

3.rememberSaveableStateHolder

rememberSaveableStateHolder() 是一个函数,会返回一个SaveableStateHolder类型的对象,顾名思义,就是一个存储rememberSaveable的容器,当页面重新切回来加入到组件树之后,rememberSaveable的内容还在。

工作流程如下:

  • 创建持有者: 在这些动态Composable的共同父级中,调用rememberSaveableStateHolder()来创建一个实例。
  • 提供状态: 将每个动态的Composable内容用saveableStateHolder.SaveableStateProvider(key = ...)包裹起来。这个key必须能唯一标识该部分内容。
  • 保存状态: 当一个SaveableStateProvider及其内容因为不再被显示而离开组件树时,SaveableStateHolder会自动保存其内部所有由rememberSaveable定义的状态,并将这些状态与你提供的key关联起来。
  • 恢复状态: 当你再次使用同一个key来组合SaveableStateProvider时,SaveableStateHolder会找到之前保存的状态并恢复它。 这确保了用户返回该界面时,能看到离开前的样子,比如滚动列表的位置或文本框中输入的内容。

下面举一个例子,在Main主屏幕中,存在4个子页面 HomeScreen()、NavScreen()、ProjectScreen()、MyScreen(),这4个页面在切换的时候,由于被saveableStateHolder.SaveableStateProvider包裹,所以会保存状态。


@Composable
fun MainScreen(){val saveableStateHolder = rememberSaveableStateHolder()Column(modifier = Modifier.padding(innerPadding)) {when (navIndex) {0 -> saveableStateHolder.SaveableStateProvider(navItems[0].label) {HomeScreen()}1 -> saveableStateHolder.SaveableStateProvider(navItems[1].label) {NavScreen()}2 -> saveableStateHolder.SaveableStateProvider(navItems[2].label) {ProjectScreen()}3 -> saveableStateHolder.SaveableStateProvider(navItems[3].label) {MyScreen()}}}

如果没有rememberSaveableStateHolder,每次切换回之前的屏幕或标签页时,其状态都会被重置,导致糟糕的用户体验。

4.主要应用场景

rememberSaveableStateHolder在以下场景中扮演着至关重要的角色:

  • 自定义导航: 在不使用官方NavHost,而是手动管理导航逻辑时,rememberSaveableStateHolder是实现页面状态保持的核心工具。 即使用户在多个屏幕之间来回跳转,每个屏幕的滚动位置等UI状态也能被完整保留。(也就是说NavHost内部自动实现了rememberSaveableStateHolder机制)
  • 带标签的界面 (Tabbed Layouts): 当用户在不同的标签页之间切换时,只有当前激活的标签页内容在组件树中。rememberSaveableStateHolder可以确保用户切换回之前的标签页时,其状态(如列表滚动位置)不会丢失。
    这里要说明一下,HorizontalPager内部也是默认实现了rememberSaveableStateHolder机制的,所以在不同Pager直接切换,Pager的rememberSaveable状态也是会有保留的。

5.SaveableStateHolder缓存内容的移除

SaveableStateHolder 中保存的内容会在以下时刻被移除:

  • 手动移除: 通过显式调用holder.removeState(key)。这是最精确的控制方式,适用于动态增删状态的场景。
  • 自动销毁: 当创建 SaveableStateHolder 的那个 Composable 自身被永久性地从组合树中移除时,holder 实例被垃圾回收,其内部保存的所有状态都会被清除。
    说得直白点,就是创建SaveableStateHolder的那个页面被NavHost出栈了,没有地方对它引用了,自然就会释放。

6.注意事项

如果使用不当,rememberSaveableStateHolder确实有可能导致内存占用过大,甚至在极端情况下增加内存溢出(OOM)的风险。
rememberSaveableStateHolder是一个强大的工具,但能力越大,责任也越大。它通过牺牲一定的内存占用换来了更好的用户体验(即时状态恢复)。这种权衡在大多数情况下是值得的,但前提是开发者必须主动管理其持有的状态生命周期,通过适时调用removeState()来防止内存无限增长。

http://www.dtcms.com/a/525571.html

相关文章:

  • 【Java】PageHelper 分页 数据重复问题
  • 网站做全局搜索wordpress怎么更换系统文件
  • 可以做国外购物的网站有哪些阿里巴巴网站建设的不足之处
  • 网站seo诊断技巧哪个网站可以找做软件兼职的
  • 赣州销售网站wordpress电视主题
  • kafka组件traceId增强
  • 【流程引擎】与【规则引擎】
  • 商业网站排名深圳市住房和建设保障局
  • PSG(巴黎圣日耳曼)技术文章大纲
  • wecenter wordpressseowhy是什么意思中文
  • 微店常用API:获取商品详情接口|关键字搜索商品接口|获取快递费接口-打通商品运营与用户体验的技术桥梁
  • 给aws xray添加采样规则
  • 圈地游戏(分数规划、网格图对偶建模)
  • 工商注册官方网站北京软件开发公司官网
  • 南充网站建设服务商互动平台
  • 电影网站html模板屋领网站固链
  • marm_ros2 机械臂视觉抓取操作流程
  • 像淘客基地这样的网站如何做网站引导页在线做
  • Wordpress 仿站 工具深圳金科威公司官网
  • python在Arcgis Pro中 多边形锐角识别与切割脚本笔记
  • 一种使用 PowerToys 的键盘管理器工具编辑惠普暗影精灵11 的 OMEN 自定义按键的方法
  • 锂电池充放电管理学习
  • 复数等式:为何对所有整数都成立?
  • CLIP模型全解析:从对比学习到零样本识别的革命
  • 广州网站优化步骤用公司网站后缀做邮箱
  • 202.快乐数
  • 黑色asp企业网站源码办公空间设计说明300字
  • 站群 网站如何做网站页面设计网页说明
  • 昆山的网站建设网站建设改手机号
  • HTML:Video视频切换时不重新加载