Android 中的 LiveDataScope 与 ViewModelScope [英] LiveDataScope vs ViewModelScope in Android

查看:48
本文介绍了Android 中的 LiveDataScope 与 ViewModelScope的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里阅读了如何使用协程https://developer.android.com/主题/库/架构/协程.让我困惑的是 LiveDataScopeViewModelScope 之间的区别.听起来 ViewModelScope 会自动处理生命周期,您可以在块中进行网络请求.当从服务器接收到数据时,将值发布到 livedata.但是当我继续阅读时,还有另一个关于 LiveDataScope 的主题对我来说似乎是多余的,因为您已经可以通过使用 ViewModelScopelivedata 来完成相同的结果代码>.这两者之间的主要区别是什么?我什么时候应该选择使用其中一种?

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 this ViewModel. This scope will be canceled when ViewModel will be cleared, i.e ViewModel.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()
        }
    }
}

请注意,您不需要显式覆盖 ViewModelonCleared() 方法来取消范围,它会自动为您执行,干杯!

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 and LiveData. The code block starts executing when LiveData becomes active and is automatically canceled after a configurable timeout when the LiveData becomes inactive. If it is canceled before completion, it is restarted if the LiveData 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 a CancelationException), it is not restarted.

我希望这是有道理的!

这篇关于Android 中的 LiveDataScope 与 ViewModelScope的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆