Android轻松搭建MVVM + Retrofit + RxJava 及嵌入Android Architecture Components(ASS架构组件)

Android轻松搭建MVVM + Retrofit + RxJava 及嵌入Android Architecture Components(ASS架构组件)_第1张图片

上面是一个简单的界面实现 ,这篇文章主要是对MVVM进行一个初步的了解,以及ASS架构的使用,非常简便的一个网络请求的封装,可以实现加载更多,加载数据,加载错误等进行生命周期的监听.不会出现当网络请求过来界面销毁导致Activity为null崩溃的问题.非常的实用..

MVVM  分为Model   View   ViewModel层

Model层 Model层就是数据层。数据来源有:

  • 本地存储数据,如数据库,文件,SharedPreferences(本质也是文件)
  • 内存的缓存或临时数据
  • 通过各种网络协议获取的远程数据

View层 :Activity/Fragment,继承至LifecycleActivity\LifecycleFragment,是UI控件的宿主。核心职责是

  • 更新UI控件显示,包括状态及数据,由ViewModel驱动
  • 监听UI事件及其生命周期,驱动ViewModel

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> 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> 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());
    

 

你可能感兴趣的:(Android,Retrofit,okhttp3,RxJava)