MutableliveData从存储库返回null到singleLiveEvent

时间:2019-01-08 07:27:45

标签: android android-volley android-architecture-components mutablelivedata android-livedata

我试图在按钮点击时呼叫网络。我使用singleLiveEvent包装器,因为需要将数据发送到服务器并仅在单击按钮时检索响应。我正在使用Volley进行GET和POST调用。我在存储库上得到响应,但在onChanged方法上却没有得到响应。它从存储库中获取空值。

Viewmodel类

 public void setResponseSingleLiveEvent(String url,Map param){

    responseSingleLiveEvent.setValue(mRepository.changeUserPassword(url,param).getValue());

}

存储库类

  public MutableLiveData<CommonServerResponse> changeUserPassword(String url, Map params) {

    this.postParams = params;

    final MutableLiveData<CommonServerResponse> responseMutableLiveData = new MutableLiveData<>();

    VolleycustomRequest<CommonModel> volleycustomRequest = new VolleycustomRequest<CommonModel>(Request.Method.POST,
            url, CommonModel.class,
            (Response.Listener<CommonModel>)
                    response -> {
                        Log.d(TAG, "changeUserPassword: "+response);

        responseMutableLiveData.setValue(new CommonServerResponse(response));
                    },
            error -> {
        responseMutableLiveData.setValue(new CommonServerResponse(VolleyErrorHelper.getMessage(error)));
            }){

        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            return params;
        }
    };

    AppController.getInstance().addToRequestque(volleycustomRequest);
    return responseMutableLiveData;
}

我希望仅在单击按钮时发送数据,而不是在活动开始时发送数据。

2 个答案:

答案 0 :(得分:0)

您的网络请求是异步的,但是您的setResponseSingleLiveEvent()方法在检查返回的LiveData的值之前没有等待它完成。

您可能希望ViewModel从存储库中传递LiveData,以便“视图”(活动/片段)可以直接订阅它:

public void onPasswordChanged(String url, Map param) {
    responseLiveData = mRepository.changeUserPassword(url, param);
}

您可能需要在网络请求进行过程中在LiveData对象中设置某种“正在加载”状态。 Google在此处提供了类似的示例:https://developer.android.com/jetpack/docs/guide#addendum

如果您只想在响应完成时使用SingleLiveEvent通知View,则可以使用Transformations.map()将结果映射到事件。

答案 1 :(得分:0)

您要在存储库给定的LiveData的ViewModal初始值中设置responseSingleLiveEvent值,该值始终为NULL。您需要在Viewmodel中收听我在演示应用程序中正在执行的操作。

  suspend fun getMovieDetail(movieId: String): LiveData<Movie> {
    moviesRepository.getMovieDetail(movieId).observeForever {
        if (it?.status == null) {
            moviesRepository.fetchFullMovieDetails(movieId, addedTime)
        }
    }
   return moviesRepository.getMovieDetail(movieId)
}

或者您可以将上下文从活动传递到视图模型,以观察并检查是否收到。您可以在此处查看完整版本

Viewmodel observe livedata