前言
上篇对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
的方法取消订阅。
BasePresenter
/**
* 基类Presenter,做统一的处理
*/
public abstract class BasePresenter {
/**
* 持有订阅
*/
protected Disposable mDisposable;
/**
* 取消订阅
*/
public void unDisposable() {
if (mDisposable != null) {
mDisposable.dispose();
}
}
}
更改继承和订阅
将LoginContract.Presenter继承BasePresenter,然后再 LoginPresenter 中赋值订阅后的结果
在LoginActivity 中取消订阅
@Override
protected void onDestroy() {
super.onDestroy();
mLoginPresenter.unDisposable();
}
至此简单完成了订阅和取消订阅的封装。
统一订阅处理
在进行subscribeWith订阅的时候,我们使用的是ResourceSubscriber这个抽象类,而又必须实现 onNext #f44336
、onError
、onComplete
这三个方法,但事实上我们只需要关注结果 onNext
方法,另外的onError
、onComplete
==都可以进行统一的处理,不必每次都进行重写。
创建BaseView
创建一个BaseView,定义两个接口:
/**
* 基类View,对统一的接口进行定义
*/
public interface BaseView {
/**
* 回调失败信息
*
* @param message 失败消息
*/
void onFailure(String message);
/**
* 完成网络请求,可以在这个方法中关闭弹出等操作
*/
void onComplete();
}
创建ApiSubscriber
创建抽象类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
进行封装,敬请期待。