android - 关于谷歌最新架构指南的 MVVM 模式,如何将数据(通知)从存储库类传递到模型 View 类

标签 android rx-java observer-pattern android-architecture-components android-livedata

我已经根据最新的 Google 架构指南开发了示例项目,

我有一个 fragment 。

MainFragment.kt

  • MainViewModel接收数据LiveData并更新运行良好的 UI

MainViewModel.kt

  • MutableLiveData<User>用户,每当我更新用户时,我的观察者在 MainFragment接到电话,我正在更新 UI(工作正常)

现在我的问题是?

  • 在我的 MainActivity我加载了两个 fragment ,MainFragment & SecondaryFragment .

    • 我有一个 Repository.kt 类,它进行 API 调用并从 SecondFragment.KT 获取用户数据

现在如何从 Repository.kt 通知 MainViewModel 我有最新数据要更新?

  • 我需要使用 RXJava 吗?从 Repository.KT 传递数据至 MainViewModel.KT ,那么我该如何使用它来传递用户数据呢?
  • Android 最新架构是否支持任何观察者完成此任务?

最佳答案

让我们分部分来:

Now how do I notify from Repository.kt to MainViewModel that I have latest data to update ?

您可以使用观察者模式,就像您从 MainViewModel 到 UI 使用的模式一样。如果你使用改造,你可以使用调用适配器从你的改造调用中返回 RxJava 的 Observables(或 Singles,Flowables 等等),所以例如你可以有这样的东西:

  @Headers({"Content-Type: application/json", "Accept: application/json"})
  @POST("/sign_in")
  Single<Response<LoginResponse>> traditionalLoginUser(
            @Body LoginRequest request,
            @Header("Authorization") String authToken);

这是一个典型的 Retrofit 接口(interface),它返回一个 Single,然后您可以在您的存储库中观察这个 Single 或简单地将它传递给 ViewModel 以在那里观察。

您还可以为 LiveData 添加一个调用适配器(google 实现了一个 here )并使用 LiveData 而不是 RxJava。不过,我个人不喜欢在网络层使用 LiveData。

do I need to use RXJava to pass the data from Repository.KT to MainViewModel.KT, in that case how do I use it to pass user data?

你可以使用 RxJava,是的。实际上,我一直在开发一个完全可以做到这一点的示例应用程序。基本思想是您使用存储库从 API 获取数据并将 Observable 传递给 ViewModel。我喜欢在 ViewModel 中做的是通过订阅其中的可观察对象(或其他 rx 实体)并接收数据来处理任何可能的错误。由于我们不一定像处理 RxJava 那样处理 LiveData 上的错误,我们可以包装 LiveData 以将错误传播到 View 作为我们包装器的状态(这实际上可以在这个 google sample 中找到)。

例如,在我的存储库中我有这个:

fun getUsersNotPaged(page: Int, pageSize: Int): Single<SOResponse<User>> {
        return remoteDataSource.apiService.getTopUsers(page, pageSize)

    }

然后在我的 View 模型中我这样做:

var userList: MutableLiveData<LiveResource<SOResponse<User>>> = MutableLiveData()

 fun getUserListNotPaged(page: Int, pageSize: Int): MutableLiveData<LiveResource<SOResponse<User>>> {
        val result = usersRepository
                .getUsersNotPaged(page, pageSize)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ result ->
                    userList.postValue(LiveResource(LiveResourceStatus.SUCCESS, result, null))
                }, { error ->
                    userList.postValue(LiveResource(LiveResourceStatus.ERROR, null, error.localizedMessage))
                })


        return userList
    }

在我看来:

 viewModel.getUserListNotPaged(1, 20).observe(this, Observer {
            it?.data?.let {
                Toast.makeText(this.context, "Here", Toast.LENGTH_SHORT).show()

            }
        })

我使用 LiveResource 来包装我的 RxJava 响应和错误。

您还可以使用 ReactiveStrems 扩展将 Rx Publisher 转换为 LiveData,但您需要处理错误时的情况发生在 ViewModel 中,并保证生成的 LiveData 没有错误。像这样:

fun getUserListNotPaged(page: Int, pageSize: Int): LiveData<SOResponse<User>> {
        val result = usersRepository
                .getUsersNotPaged(page, pageSize)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .onErrorReturn {
                   SOResponse<User>()
                }
                .toFlowable()

        return LiveDataReactiveStreams.fromPublisher(result)
    }

在这种情况下,每当出现错误时,我都会返回一个空响应。

Does Android Latest Architecture do support any observer to accomplish this?

是的,如您所见,您可以在整个过程中的所有地方或仅在过程中使用 LiveData(仅从 VM 到 UI)。有些人不同意在 HTTP 调用中使用 LiveData though (我是其中之一,哈哈)。

关于android - 关于谷歌最新架构指南的 MVVM 模式,如何将数据(通知)从存储库类传递到模型 View 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50618369/

相关文章:

java - 计算 firebase 中子节点的数量

android - Retrofit2 和 Kotlin

两个类之间的 C++ 共享对象

java - 将字符串值(日期)从 Activity 传递到另一个 fragment 的 TextView

android - 点击事件只显示一个Toast?

android - 抽屉导航(Google+ 与 YouTube)

java - 使用 RXJava 执行异步任务的推荐方法

android - 使用 RxJava 的 IdlingResource Espresso

php - 如何使用 livevalidation javascript 库 custom.validation 函数?

c# - 使用 RxCpp 构建 Observer/Observable 模式