序言:在使用mvvm架构时,官方推荐我们将网络请求等数据处理都放到ViewModel中,更好实现数据处理和数据解耦。
今天要讲的是如何通过ViewModel+LiveData实现网络请求,之所以要用上LiveData感知数据变化,就能自动刷新界面的控件初衷只是因为我们惯性把网络请求放在子线程中,而如果仅仅是将返回数据通过方法返回的话,我们可以看到页面一片空白。原因即在我们控制器跑完调用viewModel的网络请求getXXX()方法的代码后,这个时候子线程才刚刚new出,方法返回的只是null,而不是我们想要网络数据。
但后续就觉得LiveData在之后的作用也许会更大,在删除、更新等等网络接口操作再进行获取列表网络请求就能保证列表更新,这样就能离开notifyDataSetChanged()这个据说很占内存的操作。也许还有更多好处我没摸索透,之后在使用架构也许会有更多收获,当然,以后的事以后再说。
那么,开始正题吧。
1.接收返回数据的Bean类
```java
public class Bean{
private String title;
private String content;
......
}
2.ViewModel类继承AndroidViewModel
``毕竟在网络请求,我们总是跑不过Context这个上下文,当然如果各位有更好的获取Context的方法还请麻烦在评论区告诉我。
我们还要使用LiveData,所以不要忘了在声明属性时候使用MutableLiveData`
public class ViewModel extends AndroidViewModel{
// 重点
private MutableLiveData<Bean> bean;
// 获取Context
public AbarbeitungViewModel(@NonNull Application application) {
super(application);
// restrofit准备,这里不细说
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(Constant.RetrofitBaseUrl).build();
apiService = retrofit.create(APIService.class);
}
}
// get方法,控制器通过viewModel调用此方法获得网络返回数据bean
public MutableLiveData<Bean> getBean() {
if (bean==null){
bean = new MutableLiveData<>();
// 发送网络请求获取数据
getBeanList();
}
return bean;
}
// 发送网络请求
public void getAbarbeitungList(){
Call<Bean> call = apiService.getBeanList();
call.enqueue(new Callback<AbarbeitungBean>() {
@Override
public void onResponse(@NonNull Call<AbarbeitungBean> call, @NonNull Response<AbarbeitungBean> response) {
// 子线程用postValue()设置值
bean.postValue(response.body());
}
@Override public void onFailure(@NonNull Call<AbarbeitungBean> call, @NonNull Throwable t) { } });
}
到这里只要你不是写错了什么代码的话,那么已经足以申请到数据,接下来就是利用LiveData的特性,观察者来自动更新数据,这样的话我们也不怕子线程申请数据跑自己,主线程直接返回数据null给我们的控制器,导致我们页面一片空白了。
3.在控制器写下viewModel.getXX().observe()方法交由控制器监听数据变化
// 自动检测数据变化
viewModel.getBean().observe(getActivity(), new Observer<Bean>() {
@Override public void onChanged(Bean bean) {
if (bean.getMsg().equals("success")){
// 获取返回数据的列表集合
data = bean.getData();
// 设置适配器
adapter = new Adapter(data.getRecords());
}else {
Toast.makeText(getActivity(),bean.getMsg(),Toast.LENGTH_SHORT).show();
}
binding.Rv.setAdapter(adapter); } }
);
到这里今日的知识分享也结束啦,当然架构知识我也在摸索中,文章有什么错误或者更好的实现方法还请在评论区说出来。及时改正和努力学习,那么一起加油吧。(文章待优化,有优化意见可以大胆提出)