1.简介
Rxjava由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎,RxJava2是非常好用的一个异步链式库. RxAndroid是RxJava的一个针对Android平台的扩展,主要用于 Android 开发.
RxJava:a library for composing asynchronous and event-based programs using observable sequences for the Java VM// 翻译:RxJava 是一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库总结:RxJava 是一个 基于事件流、实现异步操作的库
特点:类似于 Android中的 AsyncTask 、Handler作用 基于事件流的链式调用,所以使得 RxJava:逻辑简洁实现优雅使用简单更重要的是,随着程序逻辑的复杂性提高,它依然能够保持简洁 & 优雅
2.观察者模式
生活例子引入我用一个生活例子引入 & 讲解 Rxjava原理: 多个用户订阅 天气预报,当天气变化,会通知给各个观察者
- Observable 被观察者 产生事件
- Observer 观察者 观察事件
- subscribe 订阅
- event 事件
3. 基本使用
依赖
implementation "io.reactivex.rxjava2:rxjava:2.1.3" // 必要rxjava2依赖
implementation "io.reactivex.rxjava2:rxandroid:2.0.1" // 必要rxandrroid依赖,切线程时需要用到
代码
// RxJava的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 创建被观察者 & 生产事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
// 2. 通过通过订阅(subscribe)连接观察者和被观察者
// 3. 创建观察者 & 定义响应事件的行为
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
}
}
注:整体方法调用顺序:观察者.onSubscribe()> 被观察者.subscribe()> 观察者.onNext()>观察者.onComplete()
4.常用操作符
4.1 map
对 被观察者发送的每1个事件都通过 指定的函数 处理,从而变换成另外一种事件,即 将被观察者发送的事件转换为任意的类型事件。
// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 被观察者发送事件 = 参数为整型 = 1、2、3
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
// 2. 使用Map变换操作符中的Function函数对被观察者发送的事件进行统一变换:整型变换成字符串类型
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "使用 Map变换操作符 将事件" + integer +"的参数从 整型"+integer + " 变换成 字符串类型" + integer ;
}
}).subscribe(new Consumer<String>() {
// 3. 观察者接收事件时,是接收到变换后的事件 = 字符串类型
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
4.2 flatmap
将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
原理
// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
// 采用flatMap()变换操作符
}).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("我是事件 " + integer + "拆分后的子事件" + i);
// 通过flatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
// 最终合并,再发送给被观察者
}
return Observable.fromIterable(list);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
注:新合并生成的事件序列顺序是无序的,即 与旧序列发送事件的顺序无关
4.3 concatmap
类似FlatMap()操作符与FlatMap()的 区别在于:拆分 & 重新合并生成的事件序列 的顺序 = 被观察者旧序列生产的顺序
// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
// 采用concatMap()变换操作符
}).concatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("我是事件 " + integer + "拆分后的子事件" + i);
// 通过concatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
// 最终合并,再发送给被观察者
}
return Observable.fromIterable(list);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
4.4 interval 实现倒计时功能
/** initialDelay 初始延迟时间
* period 间隔时间
* TimeUnit 时间单位
* */
final Observable<Long> observable = Observable.interval(1, 1, TimeUnit.SECONDS)
.take(4);// 倒计时 次数限制
observable.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long aLong) {
Log.d(TAG, "onNext: " + aLong);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});
5.Retrofit 结合Rxjava
5.1 添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' // 必要依赖,解析json字符所用
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' // 必要依赖,和Rxjava结合必须用到,下面会提到
implementation "io.reactivex.rxjava2:rxjava:2.1.3" // 必要rxjava2依赖
implementation "io.reactivex.rxjava2:rxandroid:2.0.1" // 必要rxandrroid依赖,切线程时需要用到
5.2 创建bean 和网络请求的接口
注意使用的是Observable对象。
public interface ApiService {
@GET("10/{page}")
Observable<Bean> getData2(@Path("page") int page);
}
5.3 创建Retrofit 实例
Retrofit build = new Retrofit.Builder()
.baseUrl(mBaseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持Rxjava
.addConverterFactory(GsonConverterFactory.create())//设置数据解析器
.build();
ApiService apiService = build.create(ApiService.class);
Observable<Bean> data = apiService.getData2(1);
5.4 处理数据
在子线程订阅该事件
在主线程观察数据的变化
对数据返回的订阅
data2.subscribeOn(Schedulers.io())// 在IO线程进行网络请求
.observeOn(AndroidSchedulers.mainThread()) // 回到主线程 处理请求结果
.subscribe(new Observer<Bean>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe: " + Thread.currentThread().getName());
}
@Override
public void onNext(Bean bean) {
Log.d(TAG, "onNext: " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: " + Thread.currentThread().getName());
}
});
6.Rxjava 源码 分析图
create方法,创建一个ObservableCreate,实现了Observable接口。其实是一个被观察者对象,内部onnext oncomplete onerror方法。
同时还传入了一个ObservableOnSubscribe对象,该对象是个回调接口而已。
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
subscribeActual()
onNext()
onComplete()
onError()
}
最终还是返回一个被观察者对象。
重要的是subscribe方法。
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
}
}
subscribeActual是个抽象方法,他的具体实现在ObservableCreate 类里。
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent); //1
try {
source.subscribe(parent);//2
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
1 是响应处理事件前的处理
2.是接口回调里,要添加具体的事件了。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("hello");
emitter.onComplete();
}
})
hello 是一个事件,onComplete也是一个事件。
CreateEmitter是ObservableEmitter的实现类。是一个包装后的发射器对象,会产生事件。CreateEmitter触发onnext onComplete onError 这些方法,会直接调用observer的诸多方法,从而实现观察者模式的效果。
static final class CreateEmitter<T> extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
RxJavaPlugins.onError(t);
}
}
}