likes
comments
collection
share

安卓开发 Jetpack Compose 的状态管理

作者站长头像
站长
· 阅读数 5

为什么会有状态管理

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

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 = "洗衣服")
)
mutableStateListOf 和 toMutableStateList

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

mutableStateListOf 和 toMutableStateList 函数会返回一个类型为 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 仅更新处于活跃生命周期状态的应用组件观察者。

如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。

使用 LiveData 的优势

使用 LiveData 具有以下优势:

  • 确保界面符合数据状态

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

  • 不会发生内存泄漏

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

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

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

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

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

  • 数据始终保持最新状态

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

  • 适当的配置更改

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

  • 共享资源

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

LiveData和ViewModel的 官方文档

在Android的官方文档中给出了一个 饮水计数的案例

我的实现

使用LiveData和ViewModel

安卓开发 Jetpack Compose 的状态管理

不使用LiveData和ViewModel

安卓开发 Jetpack Compose 的状态管理

效果

安卓开发 Jetpack Compose 的状态管理

源码

lily02

延伸

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")
}
转载自:https://juejin.cn/post/7361615299899211813
评论
请登录