安卓开发 Jetpack Compose 的状态管理

为什么会有状态管理

因为UI界面并不是一成不变的,所以需要在数据状态发生变化时更新界面,管理界面中的状态。

Flutter 的状态管理

在Flutter中有很多优秀的状态管理的库,比如Getxproviderbloc 等,基于Stream流或者 Flutter自带内置组件InheritedWidget来封装,不管是什么框架状态管理本质都是 发布-订阅模式。之前写过一篇关于Flutter的状态管理 [Flutter 状态管理的学习]

Android 中状态管理

完成一个简单的ToList

添加或删除 todo,完成todo项

让组件有状态

使用 mutableStateOfby关键字表示这是一个委托属性。

var tasks by remember { mutableStateOf(dummyTasks) }

委托属性

当你访问 tasks 属性时,实际上是委托给了 mutableStateOf(dummyTasks) 创建的状态对象,读取其中 的值。当你给 tasks 赋新值时,也是委托给了同一个状态对象,对其进行了修改。使用委托属性的好处是,你可 以将属性的底层实现委托给另一个对象,而不需要自己手动实现 getter 和 setter 方法。

rememberrememberSaveable

虽然 remember 可在重组后保持状态,只会记住重组后的,执行任何导致 Android 重新创建运行中 activity 的其他配置更改时,状态还会重置。所以横竖屏的切换,状态就会重置。要想更改配置状态依旧保留需要使用 rememberSaveable,因为rememberSaveable会自动保存可保存在 Bundle中的任何值中,

使用 remember 存储对象的可组合函数包含内部状态,这会使该可组合函数有状态

让列表成为可变列表

使用可变 ArrayList<T>mutableListOf,。这些类型不会通知列表中的项已发生更改并安排界面重组。 从列表中添加或删除任务的行为,第一步是让列表成为可变列表,创建一个可由 Compose 观的 MutableList 实例。允许 Compose 跟踪更改,以便在列表中添加或移除项时重组界面。

val dummyTasks = mutableListOf(
    Task(id = 1, title = "买菜"),
    Task(id = 2, title = "做饭"),
    Task(id = 3, title = "洗衣服")
)

mutableStateListOftoMutableStateList

mutableStateOf 函数会返回一个类型为 MutableState<T> 的对象。

mutableStateListOftoMutableStateList 函数会返回一个类型为 SnapshotStateList<T>

mutableStateListOf 不能被委托

mutableStateListOf 不能被委托的原因,委托属性需要实现 getValue()setValue() 方法。 而 mutableStateListOf本身并没有实现这两个方法,因此无法作为委托属性使用。

LiveData和ViewModel:

在官方文档的介绍中LiveDataViewModel 都是生命周期感知型组件

ViewModel

官方简介:*是一种业务逻辑或屏幕级状态容器。它用于将状态公开给界面,以及封装相关的业务逻辑。 它的主要优点是,它可以缓存状态,并可在配置更改后持久保留相应状态。 *

优势

ViewModel 类的主要优势实际上有两个方面:

  • 它允许持久保留界面状态。
  • 它可以提供对业务逻辑的访问权限。
ViewModel 的生命周期
  1. 创建阶段(onCreate): 当Activity或Fragment首次创建时,ViewModel被创建并初始化。这是ViewModel的生命周期的开始阶段。
  2. 活动阶段(active): 一旦ViewModel被创建并与Activity或Fragment相关联,它会进入活动阶段。在这个阶段,ViewModel可以被观察者观察,并且可以存储和管理与UI相关的数据。
  3. 销毁阶段(onCleared): 当Activity或Fragment被销毁时,ViewModel的onCleared()方法会被调用。在这个方法中,你可以执行一些清理工作,例如取消异步任务或释放资源。

ViewModel的生命周期超出了配置更改引起的Activity或Fragment的销毁和重新创建。这意味着,即使Activity或Fragment被销毁和重新创建,ViewModel仍然存在,并且可以保持其状态和数据。这样可以确保在配置更改后,例如屏幕旋转,用户切换了应用的语言,或者由于系统内存不足导致的重新创建,数据不会丢失,UI状态得以保持。

LiveData

官方定义是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 activity、fragment 或 service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

使用 LiveData 的优势

使用 LiveData 具有以下优势:

  • 确保界面符合数据状态

    LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 [Observer] 对象。您可以整合代码以在这些 Observer 对象中更新界面。这样一来,您无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。

  • 不会发生内存泄漏

    观察者会绑定到 [Lifecycle]对象,并在其关联的生命周期遭到销毁后进行自我清理。

  • 不会因 Activity 停止而导致崩溃

    如果观察者的生命周期处于非活跃状态(如返回堆栈中的 activity),它便不会接收任何 LiveData 事件。

  • 不再需要手动处理生命周期

    界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。

  • 数据始终保持最新状态

    如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。

  • 适当的配置更改

    如果由于配置更改(如设备旋转)而重新创建了 activity 或 fragment,它会立即接收最新的可用数据。

  • 共享资源

    您可以使用单例模式扩展 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象。

我的实现

使用LiveData和ViewModel

在这里插入图片描述

不使用LiveData和ViewModel

在这里插入图片描述

延伸

it 关键字

  1. Lambda 表达式

当使用lambda表达式时,如果lambda只有一个参数,那么可以省略参数,直接使用 it代指这个参数。


Copy code
val list = listOf(1, 2, 3, 4, 5)
list.forEach { println(it) } // 输出: 1 2 3 4 5

  1. 作用域函数

Kotlin 提供了一些作用域函数,如 letrunapplyalso等, 它们使用it代指作为其闭包的调用对象。

val str = "Hello"
str.let { println(it.length) } // 输出: 5

  1. 解构声明

在解构声明中,it可以代表被解构的对象。

data class Person(val name: String, val age: Int)
val person = Person("Alice", 25)
val (name, age) = person // name = "Alice", age = 25
println(it) // 输出: Person(name=Alice, age=25)

  1. 其他情况

在某些特殊情况下,如类型推断无法推断出正确的类型时,可以使用it作为一个临时标识符。

val map = mapOf("a" to 1, "b" to 2, "c" to 3)
map.forEach { (key, value) ->
    println("$key -> $value")
}

如果你看到了这里,觉得文章写得不错就给个赞呗?
更多Android进阶指南 可以扫码 解锁更多Android进阶资料


在这里插入图片描述
敲代码不易,关注一下吧。ღ( ´・ᴗ・` )

  • 22
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值