如何解决livedata builder 适合一次性操作吗?
例如,假设我们有一个产品目录视图,其中包含将产品添加到购物车的选项。 每次当用户点击添加到购物车时,都会调用一个 viewModel 方法 addToCart,它看起来像这样:
//inside viewModel
fun addToCart(item:Item): LiveData<Result> = liveData {
val result = repository.addToCart(item) // loadUser is a suspend function.
emit(result)
}
//inside view
addButton.onClickListener = {
viewModel.addToCart(selectedItem).observe (viewLifecycleOwner,Observer () {
result -> //show result
}
}
例如添加 5 个项目后会发生什么 -> 视图观察到的内存中是否会有 5 个 livedata 对象?
如果是,他们什么时候清理?如果是的话,我们是否应该避免使用 livedata builder 来进行可以多次调用的一次性操作?
解决方法
你的实现似乎是错误的!您不断为每个 LiveData
函数调用返回一个新的 addToCard
对象。关于你的第一个问题,它是一个 Yes
。
如果您想通过 liveData 正确执行此操作。
// In ViewModel
private val _result = MutableLiveData<Result>()
val result: LiveData<Result>
get() = _result;
fun addToCart(item: Item) {
viewModelScope.launch {
// Call suspend functions
result.value = ...
}
}
// Activity/Fragment
viewModel.result.observe(lifecycleOwner) { result ->
// Process the result
...
}
viewModel.addToCart(selectedItem)
您所要做的就是从活动中调用它并处理结果。您也可以为此使用 StateFlow
。它还有一个扩展 asLiveData
可以转换 Flow -> LiveData。
根据 LiveData
实现:
public void observe(@NonNull LifecycleOwner owner,@NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner,observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer,wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
每次观察 LiveData 时都会添加一个新的观察者 (wrapper
)。看着这个,我会小心地从视图(点击)事件中创建新的观察者。目前我不知道垃圾收集器是否可以释放这些资源。
正如@kaustubhpatange 所提到的,您应该有一个 LiveData,其状态/值可以由 viewModel 更改,每个新结果。可以在您的 Activity 或 Fragment onCreate()
函数中(一次)观察到 LiveData:
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.result.observe(lifecycleOwner) { result ->
// handle the result
}
}
在您的 ViewModel 中使用 MutableLiveData,您通常只能创建一次 LiveData,然后用来自点击事件、响应等的值填充它。
,对于一次性操作,您的方法没问题。
我认为使用 liveData
构建器没有任何内存泄漏。
例如,如果您使用 LiveData
的私有支持属性并观察公共 LiveData
,则可能会发生不同的行为,例如在为其分配新值之前获取最新值。
TL;DR
如果您的操作是 One-Shot,请使用 Coroutine
和 LiveData
。
如果您的操作使用 Streams,您可以使用 Flow
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。