上面是一个简单的界面实现 ,这篇文章主要是对MVVM进行一个初步的了解,以及ASS架构的使用,非常简便的一个网络请求的封装,可以实现加载更多,加载数据,加载错误等进行生命周期的监听.不会出现当网络请求过来界面销毁导致Activity为null崩溃的问题.非常的实用..
MVVM 分为Model View ViewModel层
Model层 Model层就是数据层。数据来源有:
View层 :Activity/Fragment
,继承至LifecycleActivity\LifecycleFragment
,是UI控件的宿主。核心职责是
ViewModel层 只做业务逻辑操作,不持有任何UI控件的引用。那数据的更新如何通知到View层,这就要仰仗ASS架构的LiveData
首先来进行一下Model层的封装,这里请求数据是通过Retrofit Rxjava 来执行,所以首先要获取到Retrofit动态代理的APi类(也就是请求接口),还有就是数据请求成功时用我们的ViewModel来设置数据.插入一段Model层的代理构造方法.这里面有二个泛型T,R T: 返回数据的类型,一般为bean类.也可以直接返回String. T: 就是Retrofit请求接口.
构造方法里传入的clazz就是我们对应不同的ViewModel,用来创建并设置数据监听,registerObserver则是对显示和隐藏加载进度条进行统一封装.
public abstract class ModelP implements IBaseModelP {
public static final int IS_NOT_NEED_SHOW_DIALOG = -1;//判断是否要显示和隐藏加载进度
public static final int IS_LOADING_MORE_DATA = 2;//加载更多数据
private CompositeDisposable mDisposable;
private R mRequest;
private BaseViewModel mBaseViewModel;
private Map map;
private String url;
private int flag;
public ModelP( Fragment fragment, Class extends BaseViewModel> clazz) {
mBaseViewModel = ViewModelProviders.of(fragment).get(clazz);
registerObserver(mBaseViewModel, fragment, null);
NetWorkManager.getInstance().getRequestManagerRetriever().get(fragment.getActivity(), this);
mRequest = NetWorkManager.getRetrofit().create(getClazz());
}
public ModelP( FragmentActivity activity, Class extends BaseViewModel> clazz) {
mBaseViewModel = ViewModelProviders.of(activity).get(clazz);
registerObserver(mBaseViewModel, null, activity);
NetWorkManager.getInstance().getRequestManagerRetriever().get(activity, this);
mRequest = NetWorkManager.getRetrofit().create(getClazz());
}
}
再来看下网络拉取数据代码,主里主要用了Rxjava的concat操作符和retryWhen操作符.
private void sendRequestToServer(R request, Observable netObservable, int flag) {
Observable cacheObservable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
handlerFirstObservable(emitter, request);
}
});
Observable concat = Observable.concat(cacheObservable, netObservable);
disposable(concat.retryWhen(new RetryWithDelay(5, 1000))
.compose(ResultTransformer.handleResult())
.compose(SchedulerProvider.getInstance().applySchedulers())
.subscribe(new Consumer() {
@Override
public void accept(T t) throws Exception {
if (flag == ModelP.IS_LOADING_MORE_DATA) {
accessMoreSuccess(t, flag);
} else {
accessSucceed(t, flag);
}
hanlerDataRequestSuccess(t);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
if (throwable instanceof ApiException) {
ApiException exception = (ApiException) throwable;
accessError(exception.getCode(), (exception).getDisplayMessage(), flag);
}
}
}));
}
concat操作符的作用是: 用来对Observable进行一个一个执行,只有上一个的执行了onComplete()方法下一个Observable才能执行.
retryWhen操作符的作用是: 对失败请求来进行再次请求
这里我们首先创建了一个cacheObservable 这里可以做获取缓存数据操作,及token失效操作及一些其它请求网络之前进行的一些操作,这里提供了一个方法来让子类实现.
第二个netObservable则是获取网络数据的操作,这里对成功的数据进行了flag判断,判断是否是加载更多的数据.
然后在获取数据的方法中对数据进行set,并对请求数据成功后提供了一个公共方法
hanlerDataRequestSuccess来决定是否对数据进行缓存处理的一些操作.
@Override
public void accessSucceed(T body, int flag) {
if (flag > IS_NOT_NEED_SHOW_DIALOG) {
mBaseViewModel.getShowDialogLiveData().setValue(false);
}
mBaseViewModel.getResultLiveData().setValue(body);
}
@Override
public void accessMoreSuccess(T body, int flag) {
if (flag > IS_NOT_NEED_SHOW_DIALOG) {
mBaseViewModel.getShowDialogLiveData().setValue(false);
}
mBaseViewModel.getMoreLiveData().setValue(body);
}
@Override
public void accessError(int code, String errorMsg, int flag) {
if (flag > IS_NOT_NEED_SHOW_DIALOG) {
mBaseViewModel.getShowDialogLiveData().setValue(false);
}
mBaseViewModel.getErrorLiveData().setValue(new RequestErrBean(code, errorMsg, flag));
}
Model层这就请完了.再来看一个ViewModel层,则更简单.这里主要有4个LiveData.
public class BaseViewModel extends ViewModel {
private MediatorLiveData resultLiveData;//获取成功数据
private MediatorLiveData moreLiveData;//获取加载更多成功数据
private MutableLiveData errorLiveData;//请求失败
private MutableLiveData showDialogLiveData;//加载框
public MediatorLiveData getResultLiveData() {
if (null == resultLiveData) {
resultLiveData = new MediatorLiveData<>();
}
return resultLiveData;
}
public MediatorLiveData getMoreLiveData() {
if (null == moreLiveData) {
moreLiveData = new MediatorLiveData<>();
}
return moreLiveData;
}
public MutableLiveData getErrorLiveData() {
if (null == errorLiveData) {
errorLiveData = new MutableLiveData<>();
}
return errorLiveData;
}
public MutableLiveData getShowDialogLiveData() {
if (null == showDialogLiveData) {
showDialogLiveData = new MutableLiveData<>();
}
return showDialogLiveData;
}
}
以上代码我们对Model及ViewModel的理解就基本结束.最后就是View层获取数据.
比如我们上面获取的城市列表的数据.首先则是创建一个CityModelP 继承ModelP,展示代码.我们则无需关心数据的来源,直接操作数据就可以.也不用关心生命周期,因为ASS架构已经帮我们处理好的.有了这玩意,我们写代码真的是越来越简单.
CityModelP mCityModelP = new CityListPresenter(this, StringViewModel.class);
mPresenter1.startRequestService(null);
CityViewModel cityViewModel = ViewModelProviders.of(this).get(CityViewModel.class);
cityViewModel.getResultLiveData().observe(this, cityListBean -> {
Log.e("onChanger", "执行了111");
mPresenter1.startRequestService(null, 2);
cityList(cityListBean.getResult().getFirstLetterCitys());
hotCityList(cityListBean.getResult().getHotCitys());
});
cityViewModel.getMoreLiveData().observe(this, cityListBean -> {
Log.e("onChanger", "执行了222");
});
cityViewModel.getErrorLiveData().observe(this, requestErrBean -> Toast.makeText(mContext, requestErrBean.msg, Toast.LENGTH_SHORT).show());