Rxjava中的ConnectableObservable
来源:互联网 发布:申请哥伦比亚大学知乎 编辑:程序博客网 时间:2024/04/29 17:40
ConnectableObservable
ConnectableObserable继承自Observable,具备Observable功能。
特点: (特别注意第2点)
1. ConnectableObservable数据并不是当观察者订阅时就发送数据,只 调用了connect()方法,才开始发送数据。2. ConnectableObservable线程切换比较特别。通过"replay"操 作符实现,而且它的"订阅"和"观察"是在同相同线程。传统的 subscribeOn()和observerOn(),不起作用,如果不通过replay指 定线程,那么它的工作线程有调用线程决定。 关于线程切换,文章后面会有用法和验证
获取ConnectableObservable实例的两种方式
publish操作符
Observable通过pulish操作符获取的ConnectableObservable和PublisSubject(对PublisSubject还不熟悉的,可以看我上一篇文章Rxjava2.0中的Subject)功能基本一样,唯一区别就是,ConnectableObservable调用connect之后才开始发射数据。
ConnectableObservable<String> connect = Observable.just("1","2","3","4","5","6").publish() ; connect.subscribe(getObserver("pob1:")) ; connect.connect() ; connect.subscribe(getObserver("pob2:")) ;
上述代码的执行结果,pob1会接收到123456,而pob2收不到任何数据
replay 操作符
- replay()
replay操作符生成的ConnectableObservable,无论观察者什么时候订阅,都能收到Observable发送的所有数据
ConnectableObservable<String> connect = Observable.just("1","2","3","4","5","6").replay() ;//订阅代码省略。。。。connect.connect(); // 开始发送数据
- replay(int buffersize)
buffersize:ConnectableObservable缓存数据源的个数,凡是在connect()之后订阅的观察者,只能收到缓存的数据,connect()之前订阅的可以收到所有数据。说白了,replay()相当于缓存了所有数据源,而replay(int buffersize)缓存指定个数的数据源。replay(long time, TimeUnit unit)
time:ConnectableObservable换存数据源的时间,凡是在connect之后time时间内订阅的,可接收到所有数据,time时间之后订阅的,收不到任何数据。connect()之前订阅的,可收到所有数据。replay(Scheduler scheduler)
指定订阅和观察所在的工作线程。replay(int buffersize, long time, TimenUnit unit)
这个方法没什么可说的,结合2、3和容易理解。replay(int buffersize, Scheduler scheduler)
指定工作线程,并指定ConnectableObservable缓存数据源的个数。replay(long time, Timeunit unit, Scheduler scheduler)
指定工作线程,并指定数据源缓存时间。replay(int buffersize, long time, TimeUnit unit, Scheduler scheduler)
这个replay涵盖了以上所有的情况,我们在此用完整代码写一遍,并验证ConnectableObservable线程切换的问题。
/** * ConnectableObservable用法和工作线程验证 * @throws InterruptedException */ public void rxJavaReplayConnectObservable() throws InterruptedException { List<String> datas = Arrays.asList("A","B","C","E","F","G") ; // 1. 缓存3个数据,保留缓存2秒钟,不指定执行线程(默认在调用线程) ConnectableObservable<String> connect = Observable.fromIterable(datas).replay(3, 2, TimeUnit.SECONDS) ; // 2. 指定在新开线程执行,此时如果显示Toast,会报错:子线程不能更新UI //ConnectableObservable<String> connect = Observable.fromIterable(datas).replay(3, 2, TimeUnit.SECONDS, Schedulers.newThread()) ; // 3. 如果使用1(即:不指定工作线程),即使在此设置订阅线程和观察线程,也不起作用 // 验证了上文所说的,ConnectableObservable只支持replay操作符指定的工作线程,下面2代码不起作用 connect.subscribeOn(Schedulers.newThread()) ; connect.subscribeOn(AndroidSchedulers.mainThread()) ; // connect()之前订阅,将收到所有数据:A、B、C、D、E、F、G connect.subscribe(getObserver("Observer-1", true)) ; // 链接,Observable开始发送数据 connect.connect() ; // 2. 如果打开休眠3秒的方法,Observer-2,因为超过了2秒的缓存,将收不到任何数据 // Thread.sleep(3000); // connect()之后订阅,只能收到缓存的3个数据:E、F、G connect.subscribe(getObserver("Observer-2", false)) ; } private Consumer<String> getObserver(final String tag, final boolean showToast){ return new Consumer<String>() { boolean isFirst = true ; @Override public void accept(@NonNull String s) throws Exception { Log.i(TAG, tag+":>>>>>>>>>"+s) ; if(isFirst && showToast){ Toast.makeText(mContext, tag+">>>>>>>显示成功", Toast.LENGTH_SHORT).show(); } } } ; }
PS:有兴趣的话,可以复制代码自己运行验证一下(我已经验证过了,不在贴运行结果了,注释很详细,而且通过修改部分参数会有很多种执行结果)。这个最复杂的replay函数会用了,其他几个简单的不在话下。
总结
因为我有Rxjava1.0的基础,所以我是通过github上的Rxjava2的例子去学习Rxjava2的,遇到不懂地方就去官方api中学习,csdn上做记录,可能有点杂乱无章,我会慢慢整理,争取慢慢进步。
阅读全文
1 0
- Rxjava中的ConnectableObservable
- Android中的RxJava详解
- Android中的RxJava
- RxJava中的错误处理
- Rxjava中的zip操作
- RxJava中的问题
- RxJava 中的map与flatMap
- RxJava中的常用操作符
- Rxjava中的toMap操作符
- RxJava 中的map与flatMap
- rxjava系列(三)-- rxjava在Android中的应用
- rxjava
- RXJava
- RXJava
- RXJava
- RxJava
- Rxjava
- RxJava
- window下cmd命令共享文件夹
- 23-事件
- Excuses, Excuses!
- Canvrs自由绘图
- Java遍历文件夹&判断是否存在某一类型的文件
- Rxjava中的ConnectableObservable
- 【转】设备树的用法(Device Tree Usage)
- 1003. 我要通过!(20)
- 项目整合Activiti关联业务(二)
- Java socket 访问网页
- linux运行级别
- 概率分析和随机算法
- 简单的viewPager和PhotoView的实现
- Android动态生成图片验证码