use*_*027 12 android android-livedata android-viewmodel kotlin-coroutines
我在这里阅读了如何使用协程https://developer.android.com/topic/libraries/architecture/coroutines。是什么让我感到困惑的是之间的差异LiveDataScope和ViewModelScope。听起来像是ViewModelScope自动处理生命周期,您可以在块中进行网络请求。当从服务器收到数据时,将值发布到livedata. 但是当我继续阅读时,还有另一个主题对LiveDataScope我来说似乎是多余的,因为您已经可以通过使用ViewModelScopewith来完成相同的结果livedata。这两者之间的主要区别是什么?我什么时候应该选择使用一个而不是另一个?
注意:如果OP 的作者已经对此有所了解,这可能是该主题的迟到答案,但为@IgorGanapolsky 的引用评论提供了一些指示。
让我们看看viewModelScope和LiveDataScope之间的主要区别是什么
官方文档说,
CoroutineScope与此相关ViewModel。这个范围会在ViewModel被清除时被取消,即被ViewModel.onCleared调用
这意味着协程范围与 ViewModel 相关联,一旦 ViewModel 被清除,该范围将通过取消所有子协程作业而被破坏。
基本上,在 MVVM 模式中,我们使用ViewModel绑定到特定的Activity/Fragment. 所以一旦它Activity/Fragment被销毁,它ViewModel就会达到清除状态。因此,它取消了所有由 开始的未viewModelScope完成作业,抛出CancellationException。
所以一个用例viewModelScope是:在ViewModel你有任何要调用的挂起函数并且需要一个 的时候CoroutineScope,尽管创建了一个新的,你可以直接从viewodel-ktx库中直接使用这个函数。
class SomeViewModel: ViewModel() {
fun someFunction() {
viewModelScope.launch {
callingSomeSuspendedFun()
callingAnotherSuspendedFun()
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要明确覆盖onCleared()的方法ViewModel来取消的范围,它会自动为你做,干杯!
现在说到LiveDataScope,它实际上是一个提供的接口,用于构建更好的支持LiveData/CoroutineLiveData,可以CoroutineScope开箱即用!使用livedata-ktx版本
现在想象一种情况,您有一个 MVVM 模式并且想要LiveData从存储库返回到视图模型。您的存储库还包含一些挂起的函数和一些协程范围。
在这种情况下,当您执行一些挂起的方法调用并将结果作为实时数据返回时,将会有一些额外的工作。在获得结果后,您需要将数据转换为特定的实时数据。看下面的例子:
class SomeRepository {
suspended fun someApiCall() : LiveData<Result> {
val result = MutableLiveData<Result>()
someCoroutineScope.launch {
val someData = someOtherCallToGetResult()
result.postValue(someData)
}
return result
}
}
Run Code Online (Sandbox Code Playgroud)
想象一下,由于LiveData对协程没有任何支持,您不得不编写上面的代码块……但直到现在!
现在,您可以直接使用liveData { }返回LiveData对象的函数,LiveDataScope以这样一种方式,您可以继续暂停的工作并在同一级别发出结果,而不是像上面那样混乱。所以上面的代码块现在可以通过以下代码或更好的代码进行优化:
class SomeRepository {
suspended fun someApiCall() : LiveData<Result> {
return liveData<Result> {
val someData = someOtherCallToGetResult()
emit(someData)
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果您将 LiveData 从存储库公开给视图模型而不是在内部视图模型中创建新的视图模型,那么在使用 MVVM 模式时,liveData 的用例将处于存储库级别。请注意,没有关于liveData不应直接在视图模型中使用方法的经验法则。如果你想viewModelScope完全避免,你可以。
查看liveData方法,
的是,该文档状态
liveData积木用作 结构化并发原语协同程序和之间LiveData。代码块在LiveData变为活动状态时开始执行,并在LiveData变为非活动状态时在可配置的超时后自动取消。如果它在完成之前被取消,如果它LiveData再次变为活动状态,它将重新启动。如果它在之前的运行中成功完成,则不会重新启动。请注意,只有在自动取消时才会重新启动。如果块因任何其他原因被取消(例如抛出 aCancelationException),则不会重新启动。
我希望这是有道理的!