我在这里阅读如何使用协程 https://developer.android.com/topic/libraries/architecture/coroutines .让我感到困惑的是 LiveDataScope
之间的区别和 ViewModelScope
.听起来像 ViewModelScope
自动处理生命周期,您可以在 block 中进行网络请求。当从服务器收到数据时,将值发送到 livedata
.但是当我继续阅读时,还有另一个关于 LiveDataScope
的话题这对我来说似乎是多余的,因为您已经可以通过使用 ViewModelScope
来完成相同的结果。与 livedata
.这两者之间的主要区别是什么?我应该在什么时候选择使用一个而不是另一个?
最佳答案
注意:如果 OP 的作者 已经对此有所了解,但为@IgorGanapolsky 的引用评论提供了一些指示,这可能是该主题的迟到答案。
让我们看看 viewModelScope 之间的主要区别是什么& LiveDataScope
1。 View 模型范围:
Official doc says that,
CoroutineScope
tied to thisViewModel
. This scope will be canceled whenViewModel
will be cleared, i.eViewModel.onCleared
is called
这意味着协程作用域与 ViewModel 相关联,一旦 ViewModel 被清除,这个作用域就会通过取消所有子协程作业来销毁。
基本上,在 MVVM 模式中,我们使用绑定(bind)到特定 Activity/Fragment
的 ViewModel
。因此,一旦 Activity/Fragment
被销毁,它的 ViewModel
就会达到清除状态。因此,它会取消所有由 viewModelScope
启动的未完成作业,并抛出 CancellationException
。
因此 viewModelScope
的一个用例是:在 ViewModel
中,当您有任何要调用的挂起函数并需要一个 CoroutineScope
,尽管创建了一个新的,但您可以直接从 viewodel-ktx 库中开箱即用。
class SomeViewModel: ViewModel() {
fun someFunction() {
viewModelScope.launch {
callingSomeSuspendedFun()
callingAnotherSuspendedFun()
}
}
}
请注意,您不需要显式重写 ViewModel
的 onCleared()
方法来取消作用域,它会自动为您完成,干杯!
2。 LiveDataScope:
现在说到LiveDataScope
,其实是为了更好地支持LiveData/CoroutineLiveData
而提供的接口(interface),可以开箱即用CoroutineScope
!使用livedata-ktx版本
现在想象一下您有一个 MVVM 模式并希望将 LiveData
从存储库返回到 View 模型的情况。您的存储库还包含一些挂起的函数和一些协程范围。
在那种情况下,当您执行一些暂停的方法调用并将结果作为实时数据返回时,会有一些额外的工作。获得结果后,您需要将数据转换为特定的实时数据。看下面的例子:
class SomeRepository {
suspended fun someApiCall() : LiveData<Result> {
val result = MutableLiveData<Result>()
someCoroutineScope.launch {
val someData = someOtherCallToGetResult()
result.postValue(someData)
}
return result
}
}
想象一下,由于 LiveData
不支持协程,您不得不编写上面的代码块……但直到现在!
现在您可以直接使用 liveData { }
函数返回您的 LiveData
对象,以这样一种方式为您提供 LiveDataScope
的范围继续暂停的工作并在同一级别发出结果,而不是像上面那样弄得一团糟。所以上面的代码块现在可以通过以下代码或更好的代码进行优化:
class SomeRepository {
suspended fun someApiCall() : LiveData<Result> {
return liveData<Result> {
val someData = someOtherCallToGetResult()
emit(someData)
}
}
}
因此,如果您将 LiveData 从存储库公开到 View 模型而不是在内部创建新的 View 模型,那么在使用 MVVM 模式时,liveData 的用例将处于存储库级别。请注意,没有关于 liveData
方法不应该直接在 viewmodel 中使用的经验法则。如果你想完全避免 viewModelScope
,你可以。
长话短说
查看 liveData方法,
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 - Android 中的 LiveDataScope 与 ViewModelScope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57698932/