一、Obserable
一个观察者(Observer)订阅一个可观察对象(Observable)。观察者对Observable发射的数据或数据序列作出响应。
val obserable = Observable.just(1)
obserable .subscribe({ t: Int? -> })
二、Single
名为Single的Observable变种
Single类似于Observable,不同的是,它总是只发射一个值,或者一个错误通知,而不是发射一系列的值。
Single只会调用这两个方法中的一个,而且只会调用一次,调用了任何一个方法之后,订阅关系终止。
Single.just("1").subscribe(object: SingleObserver<String?> {
override fun onSuccess(t: String) {
}
override fun onError(e: Throwable) {
}
override fun onSubscribe(d: Disposable) {
}
})
三、Subject
Subject可以看成是一个桥梁或者代理,它同时充当了Observer和Observable的角色。
因为它是一个Observer,它可以订阅一个或多个Observable;又因为它是一个Observable,它可以转发它收到(Observe)的数据,也可以发射新的数据。
AsyncSubject(发送最后一个数据,订阅开始发送)
一个AsyncSubject只在原始Observable完成后,发射来自原始Observable的最后一个值。(如果原始Observable没有发射任何值,AsyncObject也不发射任何值)它会把这最后一个值发射给任何后续的观察者。
如果原始的Observable因为发生了错误而终止,AsyncSubject将不会发射任何数据,只是简单的向前传递这个错误通知。val async = AsyncSubject.create<Int>() as AsyncSubject async.onNext(1) async.onNext(2) async.onNext(3) async.onComplete() async.subscribe({ t: Int? -> //这里只会输出3 }) // 不要这样使用Subject AsyncSubject.just(1, 2, 3).subscribe({ t: Int? -> })
BehaviorSubject(从订阅的上一个数据开始发送,立即发送)
BehaviorSubject会发送离订阅最近的上一个值,没有上一个值的时候会发送默认值。// 注意订阅时机,以下这个例子收不到回调 val bs = BehaviorSubject.create<Int>() // 这里订阅回调-1, 1, 2, 3 bs.onNext(1) // 这里订阅回调1, 2, 3 bs.onNext(2) // 这里订阅回调2, 3 bs.onNext(3) // 这里订阅回调3 bs.onComplete() // 这里订阅没回调 bs.subscribe({ t: Int? -> })
PublishSubject(发送开始订阅后的数据,立即发送)
PublishSubject只会把在订阅发生的时间点之后来自原始Observable的数据发射给观察者。
需要注意的是,PublishSubject可能会一创建完成就立刻开始发射数据(除非你可以阻止它发生)
方法:使用Create创建那个Observable以便手动给它引入”冷”Observable的行为(当所有观察者都已经订阅时才开始发射数据),或者改用ReplaySubject
如果原始的Observable因为发生了一个错误而终止,PublishSubject将不会发射任何数据,只是简单的向前传递这个错误通知。val ps = PublishSubject.create<Int>() // 这里订阅接收1, 2, 3 ps.onNext(1) // 这里订阅接收2, 3 ps.onNext(2) // 这里订阅接收3 ps.onNext(3) ps.onComplete() // 这里订阅无接收 ps.subscribe({ t: Int? -> })
ReplaySubject(发送所有数据,订阅开始发送)
ReplaySubject会发射所有来自原始Observable的数据给观察者,无论它们是何时订阅的。
如果你把ReplaySubject当作一个观察者使用,注意不要从多个线程中调用它的onNext方法(包括其它的on系列方法),这可能导致同时(非顺序)调用,这会违反Observable协议,给Subject的结果增加了不确定性。
要避免此类问题,
你可以将 Subject 转换为一个 SerializedSubject
mySafeSubject = new SerializedSubject( myUnsafeSubject );val bs = ReplaySubject.create<Int>() // 无论何时订阅都会收到1,2,3 bs.onNext(1) bs.onNext(2) bs.onNext(3) bs.onComplete() bs.subscribe({ t: Int? -> })
总结:假设你有一个Subject,你想把它传递给其它的代理或者暴露它的Subscriber接口,你可以调用它的asObservable方法,这个方法返回一个Observable。
四、调度器 Scheduler
如果你想给Observable操作符链添加多线程功能,你可以指定操作符(或者特定的Observable)在特定的调度器(Scheduler)上执行。
使用ObserveOn和SubscribeOn操作符,你可以让Observable在一个特定的调度器上执行,ObserveOn指示一个Observable在一个特定的调度器上调用观察者的onNext, onError和onCompleted方法,SubscribeOn更进一步,它指示Observable将全部的处理过程(包括发射数据和通知)放在特定的调度器上执行。
调度器类型 | 效果 |
---|---|
Schedulers.computation( ) | 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量 |
Schedulers.from(executor) | 使用指定的Executor作为调度器 |
Schedulers.immediate( ) | 在当前线程立即开始执行任务 |
Schedulers.io( ) | 用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器 |
Schedulers.newThread( ) | 为每个任务创建一个新线程 |
Schedulers.trampoline( ) | 当其它排队的任务完成后,在当前线程排队开始执行 |