上篇对Retrofit进行了封装,本篇将继续深入对RxJava2的线程转换、取消订阅和统一订阅结果管理相关的封装。
以下代码基本上在每个Presenter中都会使用到,每次都要重新写就比较繁琐了,而RxJava提供 compose
方法可以进行合并,具体请看 这里 ,我可没写得他好….
.subscribeOn(Schedulers.io())//运行在io线程 .observeOn(AndroidSchedulers.mainThread())//回调在主线程
将以下代码加入到BaseApi中,方便每次调用:
/** * 统一线程处理 * * @param <T> 泛型 * @return */ public static <T> FlowableTransformer<T, T> getScheduler() { //compose简化线程 return new FlowableTransformer<T, T>() { @Override public Flowable<T> apply(Flowable<T> observable) { return observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }; }
在LoginPresenter中进行调用:
在Presenter中只进行了了 == Disposable #f44336== 的订阅,但是对 Disposable 的取消订阅却没有做,如果我们在网络请求没完成的情况下关闭 Activity 或者 Fragment,就会造成 内存泄露
, 所以我们需要在 onDestroy
的时候取消订阅。
我这里的实现思路是将 Disposable
放到 BasePresenter 中,对外开放一个 unDisposable
的方法取消订阅。
/** * 基类Presenter,做统一的处理 */ public abstract class BasePresenter { /** * 持有订阅 */ protected Disposable mDisposable; /** * 取消订阅 */ public void unDisposable() { if (mDisposable != null) { mDisposable.dispose(); } } }
将LoginContract.Presenter继承BasePresenter,然后再 LoginPresenter 中赋值订阅后的结果
@Override protected void onDestroy() { super.onDestroy(); mLoginPresenter.unDisposable(); }
至此简单完成了订阅和取消订阅的封装。
在进行subscribeWith订阅的时候,我们使用的是ResourceSubscriber这个抽象类,而又必须实现 onNext #f44336
、 onError
、 onComplete
这三个方法,但事实上我们只需要关注结果 onNext
方法,另外的 onError
、 onComplete
==都可以进行统一的处理,不必每次都进行重写。
创建一个BaseView,定义两个接口:
/** * 基类View,对统一的接口进行定义 */ public interface BaseView { /** * 回调失败信息 * * @param message 失败消息 */ void onFailure(String message); /** * 完成网络请求,可以在这个方法中关闭弹出等操作 */ void onComplete(); }
创建抽象类ApiSubscriber继承至ResourceSubscriber,在ApiSubscriber中持有BaseView,实现 onError
、 onComplete
这两个方法。
/** * 统一订阅管理 * * @param <T> 泛型 */ public abstract class ApiSubscriber<T> extends ResourceSubscriber<T> { private BaseView view; public ApiSubscriber(BaseView view) { this.view = view; } public ApiSubscriber() { } @Override public void onError(Throwable t) { if (null != view) { view.onFailure(t.getMessage()); } } @Override public void onComplete() { if (null != view) { view.onComplete(); } } }
将ResourceSubscriber更换成我们的ApiSubscriber抽象类。
/** * 登陆Presenter */ public class LoginPresenter extends LoginContract.Presenter { private String TAG = "LoginPresenter"; public LoginPresenter(LoginContract.View view) { super(view); } @Override public void login(String userName, String password) { // 取消上次请求 unDisposable(); // 开始请求 mDisposable = ServiceBuild.getUserService() .login(userName, password) .compose(BaseApi.<LoginDto>getScheduler()) .subscribeWith(new ApiSubscriber<LoginDto>() { @Override public void onNext(LoginDto loginDto) { //结果回调 Log.e(TAG, "onNext: " + loginDto); if (loginDto.getCode() == 200) { view.loginSuccess(loginDto); } else { view.loginFailure(loginDto.getMessage()); } } }); } }
至于运行效果我们就不查看了,肯定是一致的,不信可以下载源码进行查看
本篇完成了对RxJava2的线程转换、取消订阅和统一订阅结果管理相关的封装,我们的代码又简洁了一部分、需要重复操心的部分也减少了一点,这也是一个大大的进步。
至此,我们的RxJava和Retrofit封装暂停一篇,下篇将先对 Dialog
进行封装,敬请期待。
源码
一个痴心妄想想成为一个全屏(栈)工程师的程序猿。
来来,关注一下吧!