【问题标题】:Android architecture components and coroutinesAndroid 架构组件和协程
【发布时间】:2020-09-21 10:35:29
【问题描述】:

那里有很多关于架构组件、kotlin 和协程的信息,但我找不到将所有这些东西结合使用的示例。 我正在努力解决如何使用here 描述的android 架构组件和协程。我有一个想法,但不确定它是否是实现这种架构风格的正确方法。 我正在尝试将视图模型 + 存储库模式与改造和协程一起使用。

我有以下存储库:

class FooRepostiroy(private val fooHttpService: FooHttpService) {
   suspend fun someMethod() : SomeResult {
       val response = fooHttpService.someRemotCall() // which is also a suspending method using retrofit-2
       // process response, store it using room and return SomeResult data object

然后我使用 ViewModel 中的 FooRepository,但由于 someMethod 是一个暂停方法,我需要将它包装在协程范围内:

class FooViewModel(private val fooRepositoru : FooRepository) : ViewModel() {
    private var someMethodJob : Job? = null
    val result : MutableLiveData<SomeResult> = MutableLiveData()

    fun someMethod() {
        someMethodJob = viewModelScope.launch {
            result.value = fooRepositoru.someMethod()
        }
    }

    override fun onCleared() {
        super.onCleared()
        someMethodJob?.cancel()
    }

然后在片段或活动中我可以观察到视图模型结果

    fooViewModel.result.observe(viewLifecycleOwner, Observer {

从我的存储库层开始,下面的一切都可以是一个暂停功能。然后从视图模型中,我可以调用任何挂起函数,但在我的视图模型中永远不会有公开暴露的挂起函数。 这是将协程与视图模型架构结合的正确方式吗?

【问题讨论】:

    标签: android kotlin android-architecture-components kotlin-coroutines


    【解决方案1】:

    这是将协程与视图模型架构结合的正确方式吗?

    是的!

    ViewModel 的每个实例都有自己的ViewModelScope

    ViewModelScope 的目的是在 ViewModel 的生命周期内运行作业,并在 ViewModel 的父 Activity/Fragment 被破坏时自动取消正在运行的协程作业。

    ViewModelScope 下的所有正在运行的作业将在ViewModel 被销毁时被取消。

    阅读更多here

    【讨论】:

    • 所以我不需要保留从launch方法返回的kotlinx.coroutines.Job的引用并在onCleared()中手动调用job.cancel()?
    • 不,你不需要手动做,这就是ViewModelScope存在的全部目的
    【解决方案2】:
    private var someMethodJob : Job? = null
    val result : MutableLiveData<SomeResult> = MutableLiveData()
    
    fun someMethod() {
        someMethodJob = viewModelScope.launch {
            result.value = fooRepositoru.someMethod()
        }
    }
    

    你可以放弃所有这些,直接说

    val result: LiveData<SomeResult> = liveData {
        emit(fooRepository.someMethod())
    }
    

    然后观察result

    【讨论】:

      猜你喜欢
      • 2019-12-15
      • 1970-01-01
      • 2019-10-24
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      相关资源
      最近更新 更多