参考:
总结:
ConnectableObservable 和它的子类以及它们的操作符:
- ConnectableObservable.connect() — 指示一个可连接的Observable开始发射数据
- Observable.publish() — 将一个Observable转换为一个可连接的Observable
- Observable.replay() — 确保所有的订阅者看到相同的数据序列,即使它们在Observable开始发射数据之后才订阅
- ConnectableObservable.refCount() — 让一个可连接的Observable表现得像一个普通的Observable
publish:
将普通Observable转换为可连接的Observable
即 : Observable-> ConnectableObservable
ConnectableObservable调用connect操作符开始发射数据,
后面的订阅者会丢失之前发射过的数据。
refCount:
将ConnectableObservable【表现】为普通Observable,可直接发送数据
share :
等价于对一个Observable同时应用publish和refCount操作,
即ConnectableObservable可直接发送数据
replay:
ConnectableObservable和普通的Observable最大的区别就是,
调用connect操作符开始发射数据,后面的订阅者会丢失之前发射过的数据。
使用Replay操作符返回的ConnectableObservable 会缓存订阅者订阅之前已经发射的数据,
这样即使有订阅者在其发射数据开始之后进行订阅也能收到之前发射过的数据。
Replay操作符能指定缓存的大小或者时间,这样能避免耗费太多内存。
publish
//Publish 操作符将普通的Observable转换为可连接的Observable(ConnectableObservable),
// ConnectableObservable是Observable的子类。
// 可连接的Observable (connectableObservable)与普通的Observable差不多,
// 不过它并不会在被订阅时开始发射数据,而是直到使用了Connect操作符时才会开始,
// 这样可以更灵活的控制发射数据的时机。
// 注意:
// 如果一个ConnectableObservable已经开始发射数据,
// 再对其进行订阅只能接受之后发射的数据,订阅之前已经发射过的数据就丢失了。
public void publish() {
final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS).take(5);
//使用publish操作符将普通Observable转换为可连接的Observable
ConnectableObservable<Long> connectableObservable = observable.publish();
//第一个订阅者订阅,不会开始发射数据
connectableObservable.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("==========onSubscribe1============");
}
@Override
public void onNext(Long aLong) {
System.out.println("==========onNext1============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("==========onError1============");
}
@Override
public void onComplete() {
System.out.println("==========onComplete1============");
}
});
//开始发射数据
System.out.println("start time=============" + sdf.format(new Date()));
connectableObservable.connect();
//第二个订阅者延迟2s订阅,这将导致丢失前面2s内发射的数据
connectableObservable
.delaySubscription(2, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("==========onSubscribe2============");
}
@Override
public void onNext(Long aLong) {
System.out.println("==========onNext2============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("==========onError2============");
}
@Override
public void onComplete() {
System.out.println("==========onComplete2============");
}
});
}
//==========onSubscribe1============
//start time=============15:53:35
//==========onSubscribe2============
//==========onNext1============0 time:15:53:36
//==========onNext1============1 time:15:53:37
//==========onNext1============2 time:15:53:38
//==========onNext2============2 time:15:53:38
//==========onNext1============3 time:15:53:39
//==========onNext2============3 time:15:53:39
//==========onNext1============4 time:15:53:40
//==========onNext2============4 time:15:53:40
//==========onComplete1============
//==========onComplete2============
connect
//connect是ConnectableObservable接口的一个方法,
// 它的作用就是让ConnectableObservable开始发射数据
// (即使没有任何订阅者订阅这个Observable,调用connect都会开始发射数据)。
// connect方法返回一个 Disposable 对象,
// 可以调用它的 dispose 方法让Observable停止发射数据给观察者。
public void connect() {
final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
//使用publish操作符将普通Observable转换为可连接的Observable
ConnectableObservable<Long> connectableObservable = observable.publish();
//开始发射数据
final Disposable disposable = connectableObservable.connect();
System.out.println("start time=============" + sdf.format(new Date()));
//订阅者延迟3s订阅,这将导致丢失前面3s内发射的数据
connectableObservable
.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("==========onSubscribe1============");
}
@Override
public void onNext(Long aLong) {
System.out.println("==========onNext1============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("==========onError1============");
}
@Override
public void onComplete() {
System.out.println("==========onComplete1============");
}
});
new Timer().schedule(new TimerTask() {
@Override
public void run() {
//6s之后停止发射数据
disposable.dispose();
}
}, 6000);
}
//start time=============16:00:12
//==========onSubscribe1============
//==========onNext1============3 time:16:00:16
//==========onNext1============4 time:16:00:17
//==========onNext1============5 time:16:00:18
refCount
//RefCount操作符可以看做是Publish的逆向,
// 它能将一个ConnectableObservable对象再重新转化为一个普通的Observable对象,
// 如果转化后有订阅者对其进行订阅将会开始发射数据,
// 后面如果有其他订阅者订阅,将只能接受后面的数据
// (这也是转化之后的Observable 与普通的Observable的一点区别 )。
// 还有一个操作符叫share,它的作用等价于对一个Observable同时应用publish和refCount操作。
public void refCount() {
final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Observable<Long> sourceObservable = Observable.interval(1, TimeUnit.SECONDS).take(5);
//使用publish操作符将普通Observable转换为可连接的Observable
ConnectableObservable<Long> connectableObservable = sourceObservable.publish();
//refCount:将ConnectableObservable转化为普通Observable
Observable<Long> refCountObservable = connectableObservable.refCount();
System.out.println("refCount time=============" + sdf.format(new Date()));
sourceObservable.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("1==========source onSubscribe1============");
}
@Override
public void onNext(Long aLong) {
System.out.println("1==========source onNext1============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("1==========source onError1============");
}
@Override
public void onComplete() {
System.out.println("1==========source onComplete1============");
}
});
//延迟三秒取五个值
sourceObservable.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("2==========source onSubscribe2============");
}
@Override
public void onNext(Long aLong) {
System.out.println("2==========source onNext2============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("2==========source onError2============");
}
@Override
public void onComplete() {
System.out.println("2==========source onComplete2============");
}
});
refCountObservable.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("3==========refCount onSubscribe1============");
}
@Override
public void onNext(Long aLong) {
System.out.println("3==========refCount onNext1============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("3==========refCount onError1============");
}
@Override
public void onComplete() {
System.out.println("3==========refCount onComplete1============");
}
});
//延迟三秒,再取值,可能丢失数据
refCountObservable.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("4==========refCount onSubscribe2============");
}
@Override
public void onNext(Long aLong) {
System.out.println("4==========refCount onNext2============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("4==========refCount onError2============");
}
@Override
public void onComplete() {
System.out.println("4==========refCount onComplete2============");
}
});
}
//refCount time=============16:12:48
//1==========source onSubscribe1============
//2==========source onSubscribe2============
//3==========refCount onSubscribe1============
//4==========refCount onSubscribe2============
//1==========source onNext1============0 time:16:12:49
//3==========refCount onNext1============0 time:16:12:49
//====> repeatCount = 1
//1==========source onNext1============1 time:16:12:50
//3==========refCount onNext1============1 time:16:12:50
//1==========source onNext1============2 time:16:12:51
//3==========refCount onNext1============2 time:16:12:51
//1==========source onNext1============3 time:16:12:52
//2==========source onNext2============0 time:16:12:52
//3==========refCount onNext1============3 time:16:12:52
//4==========refCount onNext2============3 time:16:12:52
//1==========source onNext1============4 time:16:12:53
//1==========source onComplete1============
//2==========source onNext2============1 time:16:12:53
//3==========refCount onNext1============4 time:16:12:53
//4==========refCount onNext2============4 time:16:12:53
//3==========refCount onComplete1============
//4==========refCount onComplete2============
//2==========source onNext2============2 time:16:12:54
//2==========source onNext2============3 time:16:12:55
//2==========source onNext2============4 time:16:12:56
//2==========source onComplete2============
share
它的作用等价于对一个Observable同时应用publish和refCount操作。
public void share() {
final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Observable<Long> sourceObservable = Observable.interval(1, TimeUnit.SECONDS).take(5);
// //使用publish操作符将普通Observable转换为可连接的Observable
// ConnectableObservable<Long> connectableObservable = sourceObservable.publish();
//
// //refCount:将ConnectableObservable转化为普通Observable
// Observable<Long> refCountObservable = connectableObservable.refCount();
Observable<Long> shareObservable = sourceObservable.share();
System.out.println("share time=============" + sdf.format(new Date()));
sourceObservable.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("1==========source onSubscribe1============");
}
@Override
public void onNext(Long aLong) {
System.out.println("1==========source onNext1============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("1==========source onError1============");
}
@Override
public void onComplete() {
System.out.println("1==========source onComplete1============");
}
});
//延迟三秒取五个值
sourceObservable.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("2==========source onSubscribe2============");
}
@Override
public void onNext(Long aLong) {
System.out.println("2==========source onNext2============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("2==========source onError2============");
}
@Override
public void onComplete() {
System.out.println("2==========source onComplete2============");
}
});
shareObservable.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("3==========refCount onSubscribe1============");
}
@Override
public void onNext(Long aLong) {
System.out.println("3==========refCount onNext1============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("3==========refCount onError1============");
}
@Override
public void onComplete() {
System.out.println("3==========refCount onComplete1============");
}
});
//延迟三秒,再取值,可能丢失数据
shareObservable.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("4==========refCount onSubscribe2============");
}
@Override
public void onNext(Long aLong) {
System.out.println("4==========refCount onNext2============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("4==========refCount onError2============");
}
@Override
public void onComplete() {
System.out.println("4==========refCount onComplete2============");
}
});
}
//share time=============16:37:57
//1==========source onSubscribe1============
//2==========source onSubscribe2============
//3==========refCount onSubscribe1============
//4==========refCount onSubscribe2============
//1==========source onNext1============0 time:16:37:58
//3==========refCount onNext1============0 time:16:37:58
//1==========source onNext1============1 time:16:37:59
//3==========refCount onNext1============1 time:16:37:59
//1==========source onNext1============2 time:16:38:00
//3==========refCount onNext1============2 time:16:38:00
//1==========source onNext1============3 time:16:38:01
//3==========refCount onNext1============3 time:16:38:01
//4==========refCount onNext2============3 time:16:38:01
//2==========source onNext2============0 time:16:38:01
//1==========source onNext1============4 time:16:38:02
//1==========source onComplete1============
//2==========source onNext2============1 time:16:38:02
//3==========refCount onNext1============4 time:16:38:02
//4==========refCount onNext2============4 time:16:38:02
//3==========refCount onComplete1============
//4==========refCount onComplete2============
//2==========source onNext2============2 time:16:38:03
//2==========source onNext2============3 time:16:38:04
//2==========source onNext2============4 time:16:38:05
//2==========source onComplete2============
replay:
//ConnectableObservable和普通的Observable最大的区别就是,
// 调用Connect操作符开始发射数据,后面的订阅者会丢失之前发射过的数据。
// 使用Replay操作符返回的ConnectableObservable 会缓存订阅者订阅之前已经发射的数据,
// 这样即使有订阅者在其发射数据开始之后进行订阅也能收到之前发射过的数据。
// Replay操作符能指定缓存的大小或者时间,这样能避免耗费太多内存。
public void replay() {
final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
//没有缓存的情况
ConnectableObservable<Long> connectableObservable = Observable
.interval(1, TimeUnit.SECONDS)
.take(5)
.publish();
connectableObservable.connect(); //开始发射数据
System.out.println("1 start time=============" + sdf.format(new Date()));
connectableObservable.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("1==========onSubscribe============");
}
@Override
public void onNext(Long aLong) {
System.out.println("1==========onNext============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("1==========onError============");
}
@Override
public void onComplete() {
System.out.println("1==========onComplete============");
}
});
//缓存一个数据
ConnectableObservable<Long> connectableObservable1 = Observable
.interval(1, TimeUnit.SECONDS)
.take(5)
.replay(1); //缓存1个数据
connectableObservable1.connect(); //开始发射数据
System.out.println("2 start time=============" + sdf.format(new Date()));
connectableObservable1.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("2==========onSubscribe============");
}
@Override
public void onNext(Long aLong) {
System.out.println("2==========onNext============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("2==========onError============");
}
@Override
public void onComplete() {
System.out.println("2==========onComplete============");
}
});
//缓存3s内发射的数据
ConnectableObservable<Long> connectableObservable2 = Observable
.interval(1, TimeUnit.SECONDS)
.take(5)
.replay(3, TimeUnit.SECONDS); //缓存3s
connectableObservable2.connect(); //开始发射数据
System.out.println("3 start time=============" + sdf.format(new Date()));
connectableObservable2.delaySubscription(3, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("3==========onSubscribe============");
}
@Override
public void onNext(Long aLong) {
System.out.println("3==========onNext============" + aLong +
" time:" + sdf.format(new Date()));
}
@Override
public void onError(Throwable e) {
System.out.println("3==========onError============");
}
@Override
public void onComplete() {
System.out.println("3==========onComplete============");
}
});
}
//1 start time=============16:27:18
//1==========onSubscribe============
//2 start time=============16:27:18
//2==========onSubscribe============
//3 start time=============16:27:18
//3==========onSubscribe============
//2==========onNext============2 time:16:27:21
//3==========onNext============0 time:16:27:21
//3==========onNext============1 time:16:27:21
//3==========onNext============2 time:16:27:21
//1==========onNext============3 time:16:27:22
//2==========onNext============3 time:16:27:22
//3==========onNext============3 time:16:27:22
//1==========onNext============4 time:16:27:23
//1==========onComplete============
//2==========onNext============4 time:16:27:23
//2==========onComplete============
//3==========onNext============4 time:16:27:23
//3==========onComplete============