博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RxJava2+Retrofit2优雅简洁封装
阅读量:6845 次
发布时间:2019-06-26

本文共 8080 字,大约阅读时间需要 26 分钟。

RxJava2 封装主要变化

  • Transformer的变化:RxJava1.X为rx.Observable.Transformer接口, 继承自Func1<Observable, Observable>, RxJava2.X为io.reactivex.ObservableTransformer<Upstream, Downstream>,是一个独立的接口。
  • Flowable则是FlowableTransformer,如果你使用Flowable,以下ObservableTransformer替换FlowableTransformer即可。

封装方案

1、封装 Rx 线程相关

RxSchedulersHelper:

/** * Created by weiss on 17/1/16. */public class RxSchedulers {    public static 
ObservableTransformer
io_main() { return upstream -> upstream.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); }}复制代码

封装后:

Api.getInstance().movieService                .getGankData("Android",1)                .compose(RxSchedulers.io_main());复制代码

2、封装 处理服务器返回数据,管理 RxJava生命周期

HttpResult:

/** * Created by Weiss on 2017/1/11. */public class HttpResult
implements Serializable { public String code; public String msg; public boolean hasmore; public T data; public static String SUCCESS = "000"; public static String SIGN_OUT = "101";//token验证失败 public static String SHOWTOAST = "102";//显示Toast public boolean isSuccess() { return SUCCESS.equals(code); } public boolean isTokenInvalid() { return SIGN_OUT.equals(code); } public boolean isShowToast() { return SHOWTOAST.equals(code); } public boolean hasMore() { return hasmore; }}复制代码

BaseRxActivity:

/** * 管理RxJava生命周期,避免内存泄漏 * RxJava处理服务器返回 * * Created by Weiss on 2016/12/23. */public abstract class BaseRxActivity extends BaseActivity {    private CompositeDisposable disposables2Stop;// 管理Stop取消订阅者者    private CompositeDisposable disposables2Destroy;// 管理Destroy取消订阅者者    protected abstract int getLayoutId();    protected abstract void initView();    /**     * Rx优雅处理服务器返回     *     * @param 
* @return */ public
ObservableTransformer
, T> handleResult() { return upstream ->{ return upstream.flatMap(result -> { if (result.isSuccess()) { return createData(result.data); } else if (result.isTokenInvalid()) { //处理token失效,tokenInvalid方法在BaseActivity 实现 tokenInvalid(); } else { return Observable.error(new Exception(result.msg)); } return Observable.empty(); } ); }; } private
Observable
createData(final T t) { return Observable.create(subscriber -> { try { subscriber.onNext(t); subscriber.onComplete(); } catch (Exception e) { subscriber.onError(e); } }); } public boolean addRxStop(Disposable disposable) { if (disposables2Stop == null) { throw new IllegalStateException( "addUtilStop should be called between onStart and onStop"); } disposables2Stop.add(disposable); return true; } public boolean addRxDestroy(Disposable disposable) { if (disposables2Destroy == null) { throw new IllegalStateException( "addUtilDestroy should be called between onCreate and onDestroy"); } disposables2Destroy.add(disposable); return true; } public void remove(Disposable disposable) { if (disposables2Stop == null && disposables2Destroy == null) { throw new IllegalStateException("remove should not be called after onDestroy"); } if (disposables2Stop != null) { disposables2Stop.remove(disposable); } if (disposables2Destroy != null) { disposables2Destroy.remove(disposable); } } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (disposables2Destroy != null) { throw new IllegalStateException("onCreate called multiple times"); } disposables2Destroy = new CompositeDisposable(); } public void onStart() { super.onStart(); if (disposables2Stop != null) { throw new IllegalStateException("onStart called multiple times"); } disposables2Stop = new CompositeDisposable(); } public void onStop() { super.onStop(); if (disposables2Stop == null) { throw new IllegalStateException("onStop called multiple times or onStart not called"); } disposables2Stop.dispose(); disposables2Stop = null; } public void onDestroy() { super.onDestroy(); if (disposables2Destroy == null) { throw new IllegalStateException( "onDestroy called multiple times or onCreate not called"); } disposables2Destroy.dispose(); disposables2Destroy = null; }}复制代码

封装后 (BaseRxActivity的子类使用):

addRxDestroy(Api.getInstance().movieService                .getGankData("Android",1)                .compose(RxSchedulers.io_main())                .compose(handleResult())                .省略);复制代码

handleResult为什么不新建一个类处理呢?因为很多异常处理需要context对象,或者和BaseActivity有千丝万缕的联系,BaseRxActivity继承BaseActivity可以很简洁优雅处理各种异常。比如token失效,是需要跳转到登录页面的。在新建一个类中,不能持有context对象,只能使用Application的Context,同时方便与Activity通信交互满足各种需求。BaseRxActivity还可以管理RxJava生命周期。

3、异常处理

/** * Created by Weiss on 2017/2/9. */public class RxException
implements Consumer
{ private static final String TAG = "RxException"; private static final String SOCKETTIMEOUTEXCEPTION = "网络连接超时,请检查您的网络状态,稍后重试"; private static final String CONNECTEXCEPTION = "网络连接异常,请检查您的网络状态"; private static final String UNKNOWNHOSTEXCEPTION = "网络异常,请检查您的网络状态"; private Consumer
onError; public RxException(Consumer
onError) { this.onError=onError; } /** * Consume the given value. * * @param t the value * @throws Exception on error */ @Override public void accept(T t) throws Exception { if (t instanceof SocketTimeoutException) { Log.e(TAG, "onError: SocketTimeoutException----" + SOCKETTIMEOUTEXCEPTION); ToastUtils.show(SOCKETTIMEOUTEXCEPTION); onError.accept(new Throwable(SOCKETTIMEOUTEXCEPTION)); } else if (t instanceof ConnectException) { Log.e(TAG, "onError: ConnectException-----" + CONNECTEXCEPTION); ToastUtils.show(CONNECTEXCEPTION); onError.accept(new Throwable(CONNECTEXCEPTION)); } else if (t instanceof UnknownHostException) { Log.e(TAG, "onError: UnknownHostException-----" + UNKNOWNHOSTEXCEPTION); ToastUtils.show(UNKNOWNHOSTEXCEPTION); onError.accept(new Throwable(UNKNOWNHOSTEXCEPTION)); } else { Log.e(TAG, "onError:----" + t.getMessage()); onError.accept(t); } }}复制代码

封装后 (BaseRxActivity的子类使用):

addRxDestroy(Api.getInstance().movieService                .getGankData("Android",1)                .compose(RxSchedulers.io_main())                .compose(handleResult())                .subscribe(httpResult -> adapter.setItems(data),                                new RxException<>(e ->e.printStackTrace())));复制代码

4、多页请求封装

实体类:

/** * Created by Weiss on 2017/1/20. */public class Gank extends BaseListEntity {    @Override    public Observable
>> getPage(int page) { return GankApi.getInstance().service.getGankData(param.get("gank"), page) .compose(RxSchedulers.io_main()); }}复制代码

实体类继承 BaseListEntity,实现getPage方法即可。

UI视图:

public class MainActivityFragment extends BaseRxFragment {    @BindView(R.id.ptrRecyclerView)    PtrRecyclerView ptrRecyclerView;    private MultiTypeAdapter adapter;    public MainActivityFragment() {    }    @Override    protected int getLayoutId() {        return R.layout.fragment_main;    }    @Override    protected void initView() {        ptrRecyclerView.setParam("gank","Android");        adapter = new MultiTypeAdapter();        adapter.register(Gank.class,new GankViewProvider());        ptrRecyclerView.setAdapter(adapter,new Gank());    }}复制代码

只需要写一个适配器和实体类,轻松实现多页请求,PtrRecyclerView下拉刷新和上拉加载是会自动调用getPage()方法获取数据。 PtrRecyclerView目前只是简单实现下拉刷新和上拉加载,有空会完善,当然例子也会完善。当然PtrRecyclerView的封装会根据RecyclerView原生的方法名参数,减少学习成本。

后记

还可以封装网络加载对话框,这个看个人喜好,同样以上封装同样可以看个人喜好和项目需求自由组装。

相关链接

转载于:https://juejin.im/post/5c89f8216fb9a049c1601718

你可能感兴趣的文章
企业必用之单点***
查看>>
【CSS】【12】CSS盒子的display属性
查看>>
linux下配置tomcat、resin
查看>>
oracle命令历史记录工具(rlwrap)
查看>>
CentOS提示 -bash: patch: command not found 解决办法
查看>>
分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日)
查看>>
老男孩linux技术沙龙交流活动视频分享(下)
查看>>
Windows事件日志写入SQL Server并PowerBI统计分析
查看>>
linux运维人员的成功面试总结案例分享
查看>>
iPad用户使用Mac和Windows应用软件-记Parallels Access使用体验
查看>>
.NET简谈组件程序设计之(初识NetRemoting)
查看>>
windows process activation service不能安装或启动的解决办法
查看>>
SCCM 2012 SP1系列(五)安装客户端
查看>>
Gartner:2012年应用安全Hype Cycle
查看>>
Android应用程序消息处理机制(Looper、Handler)分析(6)
查看>>
《统一沟通-微软-培训》-2-部署-反向代理-2-配置初始的部署设置
查看>>
2013年6月工作小结-- 再论需求与设计,别总去跑马拉松
查看>>
如何更有效使用 Rational AppScan 扫描
查看>>
Oracle下sqlplus无法使用命令退格删除和历史记录的解决方法--使用rlwrap
查看>>
Centos 5.5 上面Wordpress平台搭建
查看>>