一、功能操作符:辅助被观察者(Observable) 在发送事件时实现一些功能性需求
二、功能操作符按照使用功能,大致分类:
三、使用详解
//创建被观察者对象
Observable observable = Observable.just(1, 2, 3);
//创建观察者对象
Consumer integerConsumer = new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
}
};
//订阅
observable.subscribe(integerConsumer);
完成订阅后,当被观察者发送事件时,观察者会执行其实现的方法。
3、线程类型:在 RxJava
中,内置了多种用于调度的线程类型
类型 | 含义 | 应用场景 |
---|---|---|
Schedulers.immediate() | 当前线程 = 不指定线程 | 默认 |
AndroidSchedulers.mainThread() | Android主线程 | 操作UI |
Schedulers.newThread() | 常规新线程 | 耗时等操作 |
Schedulers.io() | io操作线程 | 网络请求、读写文件等io密集型操作 |
Schedulers.computation() | CPU计算操作线程 | 大量计算操作 |
RxJava
内部使用 线程池 来维护这些线程,所以线程的调度效率非常高。4、使用示例:
Observable.just(1, 2, 3)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
5、使用注意:
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.e("Thread===",Thread.currentThread().getName());
e.onNext(1);
}
}).subscribeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.e("thread===",Thread.currentThread().getName());
}
});
输出结果:
05-06 06:04:00.454 4814-4814/com.example.administrator.googleplay E/Thread===: main
05-06 06:04:00.547 4814-4814/com.example.administrator.googleplay E/thread===: main
上述过程,制定了两次订阅的线程分别为主线程和创建线程,从输出结果上看被观察者是在main线程中发送的事件,后面的newThread并未起作用,下面看看observeOn():
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
}
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.doOnNext(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.e("doOnNext Thread===",Thread.currentThread().getName());
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.e("subscribe Thread===",Thread.currentThread().getName());
}
});
上面使用了两次observeOn切换线程,如果两者都起作用,那第一个应该创建新线程,第二打印的应该是主线程,看看输出结果:
05-06 06:10:56.608 5303-5330/com.example.administrator.googleplay E/doOnNext Thread===: RxNewThreadScheduler-1
05-06 06:10:56.624 5303-5303/com.example.administrator.googleplay E/subscribe Thread===: main
输出结果与分析的一致,所以验证上面的结论:对于subscribeOn()多次调用只有第一次起作用,observeOn()每次调用都会起作用
// 1. 指定延迟时间
// 参数1 = 时间;参数2 = 时间单位
delay(long delay,TimeUnit unit)
// 2. 指定延迟时间 & 调度器
// 参数1 = 时间;参数2 = 时间单位;参数3 = 线程调度器
delay(long delay,TimeUnit unit,mScheduler scheduler)
// 3. 指定延迟时间 & 错误延迟
// 错误延迟,即:若存在Error事件,则如常执行,执行后再抛出错误异常
// 参数1 = 时间;参数2 = 时间单位;参数3 = 错误延迟参数
delay(long delay,TimeUnit unit,boolean delayError)
// 4. 指定延迟时间 & 调度器 & 错误延迟
// 参数1 = 时间;参数2 = 时间单位;参数3 = 线程调度器;参数4 = 错误延迟参数
delay(long delay,TimeUnit unit,mScheduler scheduler,boolean delayError): 指定延迟多长时间并添加调度
3、使用示例
Observable.just(1,2,3)
.delay(1, TimeUnit.SECONDS)
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
}
});
3、使用示例
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onError(new Throwable("发生错误了"));
}
})
// 1. 当Observable每发送1次数据事件就会调用1次
.doOnEach(new Consumer>() {
@Override
public void accept(Notification integerNotification) throws Exception {
Log.d(TAG, "doOnEach: " + integerNotification.getValue());
}
})
// 2. 执行Next事件前调用
.doOnNext(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "doOnNext: " + integer);
}
})
// 3. 执行Next事件后调用
.doAfterNext(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "doAfterNext: " + integer);
}
})
// 4. Observable正常发送事件完毕后调用
.doOnComplete(new Action() {
@Override
public void run() throws Exception {
Log.e(TAG, "doOnComplete: ");
}
})
// 5. Observable发送错误事件时调用
.doOnError(new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d(TAG, "doOnError: " + throwable.getMessage());
}
})
// 6. 观察者订阅时调用
.doOnSubscribe(new Consumer() {
@Override
public void accept(@NonNull Disposable disposable) throws Exception {
Log.e(TAG, "doOnSubscribe: ");
}
})
// 7. Observable发送事件完毕后调用,无论正常发送完毕 / 异常终止
.doAfterTerminate(new Action() {
@Override
public void run() throws Exception {
Log.e(TAG, "doAfterTerminate: ");
}
})
// 8. 最后执行
.doFinally(new Action() {
@Override
public void run() throws Exception {
Log.e(TAG, "doFinally: ");
}
})
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
输出结果:
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onError(new Throwable("发送异常!"));
}
}).onErrorReturn(new Function() {
@Override
public Integer apply(Throwable o) throws Exception {
Log.e("=====",o.getMessage());
return 110;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.e("=====",o + "");
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e("=====",throwable.getMessage());
}
});
输出结果:
05-06 06:43:17.498 6446-6470/com.example.administrator.googleplay E/=====: 发送异常!
05-06 06:43:17.513 6446-6446/com.example.administrator.googleplay E/=====: 1
05-06 06:43:17.513 6446-6446/com.example.administrator.googleplay E/=====: 2
05-06 06:43:17.513 6446-6446/com.example.administrator.googleplay E/=====: 3
05-06 06:43:17.513 6446-6446/com.example.administrator.googleplay E/=====: 110
在发送异常事件后首先执行了onErrorReturn输出异常信息,然后修改并返回一个数据,此数据作为一个新的事件发送,从而回掉onNext()方法。
.onErrorResumeNext(new Function() {
@Override
public ObservableSource apply(Throwable throwable) throws Exception {
return Observable.just("A","B");
}
}
注意:
<-- 1. retry() -->
// 作用:出现错误时,让被观察者重新发送数据
// 注:若一直错误,则一直重新发送
<-- 2. retry(long time) -->
// 作用:出现错误时,让被观察者重新发送数据(具备重试次数限制
// 参数 = 重试次数
<-- 3. retry(Predicate predicate) -->
// 作用:出现错误后,判断是否需要重新发送数据(若需要重新发送& 持续遇到错误,则持续重试)
// 参数 = 判断逻辑 //返回false = 不重新重新发送数据 & 调用观察者的onError()结束 //返回true = 重新发送请求(最多重新发送3次)
<-- 4. retry(new BiPredicate
使用示例:
// 作用:出现错误后,判断是否需要重新发送数据(具备重试次数限制
// 参数 = 设置重试次数 & 判断逻辑
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onError(new Exception("发生错误了"));
e.onNext(3);
}
})
// 拦截错误后,判断是否需要重新发送请求
.retry(3, new Predicate() {
@Override
public boolean test(@NonNull Throwable throwable) throws Exception {
// 捕获异常
Log.e(TAG, "retry错误: "+throwable.toString());
//返回false = 不重新重新发送数据 & 调用观察者的onError()结束
//返回true = 重新发送请求(最多重新发送3次)
return true;
}
})
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
.retryUntil(new BooleanSupplier() {
@Override
public boolean getAsBoolean() throws Exception {
return true;
}
})
注意:当返回true时表示不重复发送,其实从名字中可以看出来retryUntil ,有个Until是当达到某种条件时即可停止
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onError(new Throwable("发送异常!"));
e.onNext(3);
}
}).retryWhen(new Function, ObservableSource>>() {
@Override
public ObservableSource> apply(Observable throwableObservable) throws Exception {
return throwableObservable.flatMap(new Function>() {
@Override
public ObservableSource> apply(Throwable throwable) throws Exception {
return Observable.just(4);
}
});
}
})
输出结果:
/com.example.administrator.googleplay E/=====: 1
05-06 07:15:02.627 7459-7459/com.example.administrator.googleplay E/=====: 2
05-06 07:15:02.627 7459-7459/com.example.administrator.googleplay E/=====: 1
05-06 07:15:02.627 7459-7459/com.example.administrator.googleplay E/=====: 2
05-06 07:15:02.627 7459-7459/com.example.administrator.googleplay E/=====: 1
从上面可以看出当发送异常时会重新发送,发送数据为1,2 循环,
注:1. 若 新的被观察者 Observable发送的事件 = Error事件,那么 原始Observable则不重新发送事件:
2. 若 新的被观察者 Observable发送的事件 = Next事件 ,那么原始的Observable则重新发送事件:
现在修改上面的Observable.just(4)为 Observable.error(new Throwable("retryWhen终止啦"));,
Observable.error(new Throwable("retryWhen终止啦"));
再次运行程序,回掉onError()方法,输出结果:
05-06 07:19:35.237 8015-8015/com.example.administrator.googleplay E/=====: retryWhen终止啦
Observable.just(1, 2, 3)
.repeat()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.e("=====", o + "");
}
});
输出结果:
05-06 07:24:51.407 8210-8210/com.example.administrator.googleplay E/=====: 1
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 2
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 3
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 1
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 2
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 3
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 1
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 2
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 3
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 1
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 2
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 3
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 1
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 2
05-06 07:24:51.408 8210-8210/com.example.administrator.googleplay E/=====: 3
重载:repeat(3)参数:循环的次数,先修改传入参数2,执行程序
.repeat(2)
输出结果:
05-06 07:28:17.482 8210-8210/com.example.administrator.googleplay E/=====: 1
05-06 07:28:17.490 8210-8210/com.example.administrator.googleplay E/=====: 2
05-06 07:28:17.490 8210-8210/com.example.administrator.googleplay E/=====: 3
05-06 07:28:17.490 8210-8210/com.example.administrator.googleplay E/=====: 1
05-06 07:28:17.490 8210-8210/com.example.administrator.googleplay E/=====: 2
05-06 07:28:17.509 8210-8210/com.example.administrator.googleplay E/=====: 3
以上就是RxJava的功能操作符的介绍,功能强大之处在开发中会深有体会。