转--创建Observable操作符

https://blog.csdn.net/u013318615/article/details/82390992

前言
既然RxJava是基于观察者模式,那么就需要我们操作观察者(Observer)和被观察者(Observable),那么怎么创建Observable便是第一步。

创建Observable操作符
just():创建一个直接发射数据的Observable
from():从一个数组或列表中转换成Observable
create():创建一个Observable
defer():当订阅者订阅时才创建Observable,为每一个订阅创建一个新的Observable
range():创建一个指定范围的序列Observable
interval():创建一个按照规定时间间隔发射数据的Observable
timer():延时发射数据的Observable
empty():直接完成的Observable
error():直接发射错误的Observable
never():不发射数据的Observable
just()
// 发射数据
Observable.just("abc")
.subscribe({
JLog.d("onNext:it") }, { JLog.d("onError:it")
}, {
JLog.d("onComplete")
}, {
JLog.d("onSubscribe")
})
1
2
3
4
5
6
7
8
9
10
11
打印:

onSubscribe
onNext:abc
onComplete
1
2
3
当然,你可以使用Just发射一组数据:

Observable.just("1", "2", "3", "4", "5")
.subscribe({
JLog.d("onNext:it") }, { JLog.e("onError:it")
}, {
JLog.d("onComplete")
}, {
JLog.d("onSubscribe")
})
1
2
3
4
5
6
7
8
9
10
打印:

onSubscribe
onNext:1
onNext:2
onNext:3
onNext:4
onNext:5
onComplete

1
2
3
4
5
6
7
From()
当你使用Just发射一组数据时,你会发现它和From很相似:

Observable.fromArray("a", "b", "c")
.subscribe({
JLog.d(it)
})
val items = arrayListOf("1", "2", "3")
Observable.fromIterable(items)
.subscribe({
JLog.d(it)
})
1
2
3
4
5
6
7
8
9
打印:

a
b
c
1
2
3

1
2
3
4
5
6
create()
Observable.create(ObservableOnSubscribe<Int> {
try
{
if (!it.isDisposed)
{
for (i in 0..5)
{
it.onNext(i)
}
it.onComplete()
}
} catch (e: Exception)
{
it.onError(e)
}
}).subscribe({
JLog.d("onNext->it") }, { JLog.e("onError->it")
}, {
JLog.d("onComplete")
}, {
JLog.d("onSubscribe")
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
打印:

onSubscribe
onNext->0
onNext->1
onNext->2
onNext->3
onNext->4
onNext->5
onComplete     

1
2
3
4
5
6
7
8
Defer()
defer操作符,直到有订阅者订阅它的时候,它才会创建一个Observable,以确保获取的数据是最新的

var a = 1
val defer = Observable.defer {
Observable.just(a)
}
val just = Observable.just(a)
a++
just.subscribe({ JLog.d("just:" + it.toString()) })
defer.subscribe({
JLog.d("defer:" + it.toString())
})
1
2
3
4
5
6
7
8
9
10
我在a=1的时候用defer和just分别创建了一个Observable,在a++之后才消费他们,首先看一下结果:

just:1
defer:2
1
2
可以看到,just在创建的时候发射数据已经确定,而defer在有订阅的时候才会创建Observable,保证了a是最新值

Timer()
延时操作符,默认在computation调度器上执行,会在延时一段时间后发射数据

Observable.timer(2, TimeUnit.SECONDS)
.subscribe(object : Observer<Long>
{
override fun onComplete()
{
}

          override fun onSubscribe(d: Disposable)
          {
              JLog.d("onSubscribe")
          }

          override fun onNext(t: Long)
          {
              JLog.d("onNext")
              JLog.d("onNext发射结果:$t")
          }

          override fun onError(e: Throwable)
          {
              JLog.e(e.toString())
          }
      })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
打印结果:

10-15 17:40:22.734 19180-19180/com.jzd.jutils.app D/JLog: onSubscribe
10-15 17:40:24.735 19180-19627/com.jzd.jutils.app D/JLog: onNext
onNext发射结果:0
1
2
3
timer在延时2s后反射了一个0

Interval()
间隔操作符,默认在computation调度器上执行,会在固定时间间隔后发射数据

Observable.interval(1, TimeUnit.SECONDS)
.subscribe({ JLog.d(it.toString()) })
1
2
打印结果

10-15 17:44:15.022 21811-21902/com.jzd.jutils.app D/JLog: 0
10-15 17:44:16.021 21811-21902/com.jzd.jutils.app D/JLog: 1
10-15 17:44:17.021 21811-21902/com.jzd.jutils.app D/JLog: 2
10-15 17:44:18.021 21811-21902/com.jzd.jutils.app D/JLog: 3
10-15 17:44:19.021 21811-21902/com.jzd.jutils.app D/JLog: 4
10-15 17:44:20.021 21811-21902/com.jzd.jutils.app D/JLog: 5
1
2
3
4
5
6
interval也有3个参数的创建方法interval(long initialDelay, long period, TimeUnit unit)先指定延时时间,然后再轮询发送。。。不过,如果你第一次用interval,你会发现这样写,interval创建的发射器根本停不下来啊,有木有~坑爹啊。所以正确的操作方式应该是这样的:

Observable.intervalRange(10, 5, 1, 1, TimeUnit.SECONDS)
.subscribe({ JLog.d(it.toString()) })
1
2
对应的方法就是intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit)

Repeat
Repeat操作符可以配合创建操作符使用,在创建时配置重复策略
使用repeat重复发射一组数据

Observable.just("1", "2", "3")
.repeat(2)
.subscribe({ JLog.d(it) })
1
2
3
打印

1
2
3
1
2
3

1
2
3
4
5
6
使用repeatWhen

Observable.just("1")
.repeatWhen { Observable.timer(3, TimeUnit.SECONDS) }.subscribe({ JLog.d(it) })
JLog.d("---------------------------")
1
2
3
打印

10-15 19:49:01.646 5814-5814/com.jzd.jutils.app D/JLog: 1
---------------------------
10-15 19:49:04.646 5814-6133/com.jzd.jutils.app D/JLog: 1
1
2
3
可以看到3秒后重复发送了一次数据
使用repeatUntil

var count = 0
Observable.just("测试")
.repeatUntil { count >= 5 }
.subscribe({
JLog.d("第{count++}次:it")
})
1
2
3
4
5
6
打印结果:

第0次:测试
第1次:测试
第2次:测试
第3次:测试
第4次:测试
1
2
3
4
5
可以看到,repeatUntil(BooleanSupplier stop)中,当getAsBoolean返回false时会重复发射数据,当返回true时,会终止发射数据。
常用的创建操作符基本介绍完了,使用这些操作符,我们就可以愉快的创建各式各样的Observable了。
————————————————
版权声明:本文为CSDN博主「Jzd_dev」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013318615/article/details/82390992

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容

  • 注:只包含标准包中的操作符,用于个人学习及备忘参考博客:http://blog.csdn.net/maplejaw...
    小白要超神阅读 2,190评论 2 8
  • 前言:上篇文章我们讲解了RxJava最基本的基础知识原理,这篇呢我打算讲解下怎么来创建一个observable被观...
    六_六阅读 237评论 0 0
  • 注:只包含标准包中的操作符,用于个人学习及备忘参考博客:http://blog.csdn.net/maplejaw...
    小白要超神阅读 921评论 0 3
  • 一、RxJava操作符概述 RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易...
    无求_95dd阅读 3,038评论 0 21
  • 一、RxJava操作符概述 RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易...
    测天测地测空气阅读 630评论 0 1