【问题标题】:How to communicate between a Repository and ViewModel class when Retrofit either fails or success with an requests?当 Retrofit 请求失败或成功时,如何在 Repository 和 ViewModel 类之间进行通信?
【发布时间】:2020-01-20 22:24:19
【问题描述】:

多年来,我一直在使用 MVP 模式开发 Android 应用程序,但我现在正在尝试学习 MVVMViewModelLiveData

在以下示例中,我不知道如何通过 Retrofit 发送 POSTGET 请求来传达失败或成功结果

在使用 MVP 之前,我会使用 Listener 与 listener.onTodoFetched()listener.onTodoFetchError() 通信演示者,然后根据调用的方法做出不同的反应。我还应该以这种方式与我的ViewModel 班级交流吗?

FetchTodoRepository.java

public MutableLiveData<String> fetchTodo() {
    retrofitService.getRetrofitService().create(Endpoints.class).getTodo().enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {

            if (response.isSuccessful() && response.body() != null) {
                listener.onTodoFetched(response.body());     //ViewModel equivalent?
            } else {
                listener.onTodoFetchError(response.message());     //ViewModel equivalent?
            }

        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {
            listener.onTodoFetchError(t.getMessage());     //ViewModel equivalent?
        }
    });

    return mutableLiveData;
}

更新:

根据答案和进一步的研究,可以使用以下方法:

  • 类之间的普通 Java 侦听器
  • RxJava
  • Kotlin 高阶函数。

【问题讨论】:

  • 如果你使用 RX 会更容易,twith RX 你可以在成功/失败时观察响应和发布值。但是对于侦听器,我会在 VM 中创建 LiveData 变量(例如,1 用于成功(字符串),2 用于错误(枚举)。然后在您的侦听器上,您可以使用方法 postValue() 在您的变量上发布数据。之后是否要使用 DataBinding 或观察片段/活动中的 LiveData 以进行更改取决于您。
  • 所以在MVVM 中使用RxJava 或普通Java 侦听器在RepositoryViewModel 之间进行通信不会错吗?
  • 普通的监听器很好,因为你还在使用 Java,RxJava 将是一个不错的选择,但是,我还想提一下,如果你打算使用 Kotlin 或协程,Retrofit默认支持挂起函数,更容易与 MVVM 架构和 LiveData 结合。
  • @RodrigoQueiroz 所以我的方法 fetchTodo() 实际上不必返回 MutableLiveData 的对象,如果我使用 Listener 或 RxJava 将结果返回到 ViewModel

标签: android mvvm android-livedata android-viewmodel


【解决方案1】:

Repository 和 ViewModel 之间使用Higher-Oder Functions 进行通信 将函数作为参数传递到存储库方法中

例如在 Repository 方法中是这样的:

fun repoMethod(id : Int, viewModelCallBack : (List<CustomeDto>) -> Unit)
{
     //Your API call
     .....
    viewModelCallBack(response.body())

}

和查看模型方法一样

    fun viewModelMethod()
    {
       repoObj.repoMethod(5){ listOfValueReturnFromApi ->
            //Here listOfValueReturnFromApi is API response using Higher Order function in kotlin
        }

    }

【讨论】:

    【解决方案2】:

    当您将 mvvm 与 livedata 一起使用时,您实际上不需要使用接口将数据传递给 viewmodel。

    MutableLiveData 有方法 setValue() 在其中传递您的响应,然后当您在 viewmodel 中调用此 fetchTodo() 方法时,您将获得所有数据。

    试试下面的代码

      public MutableLiveData<String> fetchTodo() {
    retrofitService.getRetrofitService().create(Endpoints.class).getTodo().enqueue(new 
    Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
    
            if (response.isSuccessful() && response.body() != null) {
                mutableLiveData.setValue(response.body())
            } else {
                 mutableLiveData.setValue(response.message());    
            }
    
        }
    
        @Override
        public void onFailure(Call<String> call, Throwable t) {
             mutableLiveData.setValue(t.message());    //ViewModel equivalent?
        }
    });
    
    return mutableLiveData;
    }
    

    在您的视图模型中:

     public LiveData<String> fetchTodo()
    {
     return yourRepoInstance.fetchTodo() ; here you will get result data
    }
    

    【讨论】:

    • 我如何区分成功和失败的结果,就像我可以对两个不同的听众做的那样?
    【解决方案3】:

    很容易实现。

    只需使用 HTTP 状态码。作为响应,您将获得状态代码,只需将其发送到 viewmodel,然后在 viewmodel 中您可以通过观察它轻松地将其发送到 Activity 或 Fragment。

    例如。 200 - 好的 400 - 错误请求等。

    我不知道它对你有没有帮助,但这对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      • 2013-10-02
      • 2018-06-05
      • 1970-01-01
      • 2021-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多