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

15 篇文章 0 订阅
7 篇文章 0 订阅

上面是一个简单的界面实现 ,这篇文章主要是对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<T, R> implements IBaseModelP<T> {
    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<T> mBaseViewModel;
    private Map<String, Object> map;
    private String url;
    private int flag;


    public ModelP( Fragment fragment, Class<? extends BaseViewModel<T>> 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<T>> 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<T> netObservable, int flag) {
        Observable<T> cacheObservable = Observable.create(new ObservableOnSubscribe<T>() {
            @Override
            public void subscribe(ObservableEmitter<T> emitter) throws Exception {

                handlerFirstObservable(emitter, request);
            }
        });

        Observable<T> concat = Observable.concat(cacheObservable, netObservable);


        disposable(concat.retryWhen(new RetryWithDelay(5, 1000))
                .compose(ResultTransformer.handleResult())
                .compose(SchedulerProvider.getInstance().applySchedulers())
                .subscribe(new Consumer<T>() {
                    @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<Throwable>() {
                    @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<T> extends ViewModel {

    private MediatorLiveData<T> resultLiveData;//获取成功数据
    private MediatorLiveData<T> moreLiveData;//获取加载更多成功数据
    private MutableLiveData<RequestErrBean> errorLiveData;//请求失败
    private MutableLiveData<Boolean> showDialogLiveData;//加载框

    public MediatorLiveData<T> getResultLiveData() {
        if (null == resultLiveData) {
            resultLiveData = new MediatorLiveData<>();
        }
        return resultLiveData;
    }

    public MediatorLiveData<T> getMoreLiveData() {
        if (null == moreLiveData) {
            moreLiveData = new MediatorLiveData<>();
        }
        return moreLiveData;
    }

    public MutableLiveData<RequestErrBean> getErrorLiveData() {
        if (null == errorLiveData) {
            errorLiveData = new MutableLiveData<>();
        }
        return errorLiveData;
    }

    public MutableLiveData<Boolean> 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());
    

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值