Android 中的 LiveDataScope 与 ViewModelScope [英] LiveDataScope vs ViewModelScope in Android
问题描述
我在这里阅读了如何使用协程https://developer.android.com/主题/库/架构/协程.让我困惑的是 LiveDataScope
和 ViewModelScope
之间的区别.听起来 ViewModelScope
会自动处理生命周期,您可以在块中进行网络请求.当从服务器接收到数据时,将值发布到 livedata
.但是当我继续阅读时,还有另一个关于 LiveDataScope
的主题对我来说似乎是多余的,因为您已经可以通过使用 ViewModelScope
和 livedata> 来完成相同的结果代码>.这两者之间的主要区别是什么?我什么时候应该选择使用其中一种?
I was reading how to use coroutines here https://developer.android.com/topic/libraries/architecture/coroutines. What makes me confused about is the difference between LiveDataScope
and ViewModelScope
. It sounds like ViewModelScope
takes care of lifecycle automatically and you can do network request in the block. When data received from server, post the value to livedata
. but then when I continued to read, there's another topic about LiveDataScope
which seems redundant to me since you can already accomplish the same result by using ViewModelScope
with livedata
. What is the main difference between those two? and when should I choose to use one over the other?
推荐答案
注意:如果 OP 的作者 已经对此主题有所了解,这可能是该主题的迟到答案, 但为@IgorGanapolsky 的引用注释提供了一些指针.
Note: This might be late answer for this topic if Author of OP already has understanding about this, But providing some pointers for the referencing comment of @IgorGanapolsky.
让我们看看 viewModelScope 之间的主要区别是什么 &LiveDataScope
官方文档说,CoroutineScope
绑定到这个 ViewModel
.这个当 ViewModel
被清除时,范围将被取消,即ViewModel.onCleared
被调用
Official doc says that,
CoroutineScope
tied to thisViewModel
. This scope will be canceled whenViewModel
will be cleared, i.eViewModel.onCleared
is called
意味着协程范围与 ViewModel 相关联,一旦 ViewModel 被清除,此范围将通过取消所有子协程作业来销毁.
Meaning that coroutine scope is tied to ViewModel, and once ViewModel gets cleared this scope gets destroyed by cancelling all child coroutine jobs.
基本上,在 MVVM 模式中,我们使用与特定 Activity/Fragment
相关联的 ViewModel
.因此,一旦 Activity/Fragment
被销毁,它的 ViewModel
就会达到清除状态.因此,它取消了由 viewModelScope
启动的所有未完成的作业,抛出 CancellationException
.
Basically, in MVVM pattern we use ViewModel
tied to a particular Activity/Fragment
. So once that Activity/Fragment
gets destroyed, its ViewModel
reaches a cleared state. Thus, it cancels all incomplete jobs started by viewModelScope
, throwing CancellationException
.
因此,viewModelScope
的用例是:在 ViewModel
内部,当您要调用任何挂起的函数并需要一个 CoroutineScope
,尽管创建了新的,但您可以直接从 viewodel-ktx 库中直接使用这个.
So a usecase of viewModelScope
is: inside ViewModel
when you've got any suspended function to be called and need a CoroutineScope
, inspite of making new one you can directly use this one out of the box from viewodel-ktx library.
class SomeViewModel: ViewModel() {
fun someFunction() {
viewModelScope.launch {
callingSomeSuspendedFun()
callingAnotherSuspendedFun()
}
}
}
请注意,您不需要显式覆盖 ViewModel
的 onCleared()
方法来取消范围,它会自动为您执行,干杯!
Note that you don't need to explicitly override onCleared()
method of ViewModel
to cancel the scope, it does automatically for you, cheers!
现在说到LiveDataScope
,它实际上是一个提供对LiveData/CoroutineLiveData
更好的支持的接口,可以让CoroutineScope
开箱即用!使用 livedata-ktx 版本
Now speaking of LiveDataScope
, it's actually an interface provided to build better support for LiveData/CoroutineLiveData
that can have CoroutineScope
out of the box! use livedata-ktx version
现在假设您有一个 MVVM 模式并且想要将 LiveData
从存储库返回到视图模型.您的存储库还包含一些挂起的函数和一些协程范围.
Now imagine a situation that you're having a MVVM pattern and wanted to return LiveData
from repository to view model. your repository also contains some suspended functions and some coroutine scope.
在那种情况下,当您执行一些挂起的方法调用 &将结果作为实时数据返回,会有一些额外的工作.在获得数据后,您需要将数据转换为特定的实时数据.看下面的例子:
In that situation when you do some suspended method calls & return the result as live data, there would be some extra work. you'll need transform your data to particular live data after getting it as result. see the example below:
class SomeRepository {
suspended fun someApiCall() : LiveData<Result> {
val result = MutableLiveData<Result>()
someCoroutineScope.launch {
val someData = someOtherCallToGetResult()
result.postValue(someData)
}
return result
}
}
想象一下,由于 LiveData
没有对协程的任何支持,你不得不编写上面的代码块......但直到现在!
Imagine you had to write above code block due to LiveData
didn't had any support for Coroutines ... but until now!
现在您可以直接使用 liveData { }
函数返回您的 LiveData
对象,从而以这样的方式为您提供 LiveDataScope
的范围继续您暂停的工作并在同一级别发出结果,而不是像上面那样弄乱.所以上面的代码块现在可以通过以下代码或更好的代码进行优化:
Now you can directly use liveData { }
function that returns you LiveData
object giving you scope of LiveDataScope
in such a way that you can continue your suspended work and emit the result at the same level rather than getting it messy way like above. So above code block can now optimized by following code or better:
class SomeRepository {
suspended fun someApiCall() : LiveData<Result> {
return liveData<Result> {
val someData = someOtherCallToGetResult()
emit(someData)
}
}
}
因此,如果您将 LiveData 从存储库公开给视图模型而不是在内部视图模型中创建新的视图模型,那么在使用 MVVM 模式时,liveData 的用例将处于存储库级别.请注意,没有关于 liveData
方法的拇指规则不应直接在视图模型中使用.如果你想完全避免 viewModelScope
,你可以.
So use case of liveData would be at repository level when using MVVM pattern if you expose LiveData to viewmodel from respository rather than creating new inside viewmodel. Please note that there's no thumb rule about liveData
method shouldn't be used at viewmodel directly. You can if you want to avoid viewModelScope
completely.
查看 liveData 方法,
Check out the liveData method,
Doc 指出,liveData
构建块用作协程和 LiveData
之间的结构化并发原语.当 LiveData
变为激活并在可配置的超时后自动取消LiveData
变为非活动状态.如果在完成之前取消,如果 LiveData
再次激活,它会重新启动.如果它在上一次运行中成功完成,它不会重新启动.笔记只有在自动取消时才会重新启动.如果块是由于任何其他原因取消(例如抛出一个CancelationException
),不重启.
Doc states that, The
liveData
building block serves as a structured concurrency primitive between coroutines andLiveData
. The code block starts executing whenLiveData
becomes active and is automatically canceled after a configurable timeout when theLiveData
becomes inactive. If it is canceled before completion, it is restarted if theLiveData
becomes active again. If it completed successfully in a previous run, it doesn't restart. Note that it is restarted only if canceled automatically. If the block is canceled for any other reason (e.g. throwing aCancelationException
), it is not restarted.
我希望这是有道理的!
这篇关于Android 中的 LiveDataScope 与 ViewModelScope的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!