Rxjava线程调度的封装
在我们使用Rxjava的时候,经常会有这么个情况,在子线程处理耗时操作,然后在主线程中处理结果。这个时候就要用到线程调度了,基本上代码如下
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
/*
* 这里用来处理一些耗时操作
* */
}
}).subscribeOn(Schedulers.io())//被观察者在子线程中处理
.observeOn(AndroidSchedulers.mainThread())//将结果发送到主线程中处理
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
/*
这里处理结果,是在主线程中
* */
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
通常情况下,在子线程中处理了耗时操作,在主线程中更新ui的情况在Android中非常常见,也就是说,我们每次都要写如下这种代码
subscribeOn(Schedulers.io())//被观察者在子线程中处理
observeOn(AndroidSchedulers.mainThread())//将结果发送到主线程中处理
虽然说也就两句话而已,但是,我这种强迫症表示受不了。于是,还是将线程调度这个封装一下吧。
package com.yzq.common.rx;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by yzq on 2018/1/10.
* 封装通用的线程调度
*/
public class CommonSchedulers {
public static <T> ObservableTransformer<T, T> io2main() {
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
}
}
上面的代码就是将一个Observable传进去,通过ObservableTransformer操作符将Observable转换成已经完成线程调度的Observable。
使用方法
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
/*
* 这里用来处理一些耗时操作
* */
}
}).compose(CommonSchedulers.<String>io2main())//这里调用一下即可
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
/*
这里处理结果,是在主线程中
* */
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
Observer的封装
虽然上面封装了一下线程调度,但是,并没有减少多少代码。感觉封不封其实差别不大。接下来,我们来对Observer进行一下封装。
我们通常都有这种需求,请求一个接口的时候,先显示一个进度框,请求完成或错误的时候隐藏进度框,做下一步操作。
大概代码就是这样
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
/*
* 这里用来处理一些耗时操作
* */
}
}).compose(CommonSchedulers.<String>io2main())//这里调用一下即可
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
/*显示进度框*/
}
@Override
public void onNext(String s) {
/*
这里处理结果,是在主线程中
* */
}
@Override
public void onError(Throwable e) {
/*隐藏进度框,显示错误的提示信息*/
}
@Override
public void onComplete() {
/*隐藏进度框*/
}
});
其实,在大多数情况下,显示进度框,隐藏进度框的时机这些都是一样,那么,我们就可以简单的封装一下,可以少些一些代码。
package com.yzq.common.rx;
import com.yzq.common.utils.LogUtils;
import com.yzq.common.utils.NetworkUtils;
import com.yzq.common.utils.ToastUtils;
import java.util.concurrent.TimeoutException;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
/**
* Created by yzq on 2018/1/9.
* 封装的BaseObserver
*/
public abstract class BaseObserver<T> implements Observer<T> {
@Override
public void onSubscribe(Disposable d) {
//这里可以显示进度框
}
@Override
public abstract void onNext(T t);
@Override
public void onError(Throwable e) {
//这里用来隐藏进度框,还可以提示错误消息
if (NetworkUtils.isConnected()) {
if (e instanceof TimeoutException) {
ToastUtils.showShort("连接服务器超时");
}
} else {
ToastUtils.showShort("无网络,请检查");
}
}
@Override
public void onComplete() {
LogUtils.i("onComplete");
//这里用来隐藏进度框
}
}
使用方法:
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
/*
* 这里用来处理一些耗时操作
* */
}
}).compose(CommonSchedulers.<String>io2main())//这里调用一下即可
.subscribe(new BaseObserver<String>() {
@Override
public void onNext(String s) {
/*只需要处理结果 不用关心进度框的问题*/
}
});
这样一来,代码就少了很多。
如果使用的是kotlin的话,可以看下面这篇文章,非常好用
Kotlin基于RxJava的扩展方法(超级好用)
如果你觉得本文对你有帮助,麻烦动动手指顶一下,算是对本文的一个认可,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!