RxJava做为近年来最火的开源库之一真是让人又爱又恨,既让人有欣喜又让人抓狂。身边也有不少小伙伴说RxJava太好用了,也有人说RxJava太难用了。RxJava到底是什么呢?简单来说就两个字——异步!
这是RxJava在GitHub的自我介绍:RxJava是一个运行在JVM上的反应扩展库,一个基于事件可以用JAVA JVM的可观测序列组合库。很具体也很抽象,至少我最开始看的时候心里一片迷茫。啥?啥?啥?这说的都是啥?不管说的是什么,总要试着学用,熟能生巧,用多了总会明白的。
本人专业度不是特别强,行文也还凑合,大家就凑合着看吧,我尽量说的明白点。
话不多说,我们先看一个例子:
因为新建APP的时候忘记选择Java了所以就用Kotlin说明了,大意一样,其他页面是Java语言,只有MainActivity是Kotlin。点击事件就不说了。我们看到有几个单词Flowat,just,subscribe,Consumer,我们一个一个介绍。
可能以前了解过RxJava的小伙伴都知道使用RxJava大概有这么几个步骤:
1、创建被观察者 (Observable/Flowat)
2、创建观察者 (Observer/Subscriber)
3、建立订阅事件(subscibe)
首先我们先看一段代码
btnRxJava.setOnClickListener {
Flowable.just("1", "2", "3", "4").subscribe(Consumer {it->
Log.d(TAG, "onNext:$it");
});
}
这是RxJava测试的代码,一个简单间写模式,Flowale就是被观察者,通过subscribe建立了关系,回调给了Consume。点击查看效果:
通过打印出来的内容我们很容易看到,很显然,Flowable将字段"1","2","3","4"传递出来了。是不是很简单呢?!我们点击just方法进去看下just方法的源码,我们看到,just接受四个泛型结构的参数,并帮你判断了是不是空值,然后返回一个数组,至于为什么返回了一个数组,我们往下看。通过查看源码我们发现Just方法最多可以接收十个参数,如果想传递更多的参数该怎么办呢?不用担心,RxJava已经替我们考虑好了,我们现在看下一个使用方法,传递不确定长度的数组数据
聪明的你肯定发现了问题对吗?对了,就是上图中的fromArray方法,我们先不看代码,我们先进入到fromArray方法看看
看源码好像并没有什么发现(当然你一直往下走肯定能找到,嘿嘿),既然发现不了我们就尝试写写,看看可以吗,不知名的名人说过,动手是最好的学习方式,一顿操作猛如虎,代码如下
btnRxArray.setOnClickListener {
val stringArray:Array<String> = arrayOf("aa", "bb", "cc")
Flowable.fromArray(stringArray).subscribe(Consumer { it->
Log.d(TAG, "onNext:$it");
})
}
点击运行,看样子好像不行,不报错,也没运行出我们想要的东西,为什么呢?
又重新看了下代码也没发现错误,最后写了一遍Java用Kotlin编译了下才知道(最近也是尝试用Kotlin写东西,很多东西不太ing吧),原来是在fromarray方法内添加数组要加*号。再次运行,看到我们想要的结果了!至于为什么要加*号,我想应该是Kotlin的特性吧,具体原因待考察
当然写到这里很多用过RxJava1.0的程序员会有疑问(我并没有用过1.0的版本),以前都是用的Observable,这个被舍弃了吗?告诉你,并没有,Observable依然也在用,只是RxJava最新版github用这个做例子我也直接拿来写了,那我们先看下Observable的写法,先把Flowable的代码注释掉,点击运行:
btnRxArray.setOnClickListener {
// val stringArray:Array<String> = arrayOf("aa", "bb", "cc")
// Flowable.fromArray(*stringArray).subscribe(Consumer { it->
// Log.d(TAG, "onNext:$it");
// })
Observable.fromArray(*stringArray).subscribe(Consumer {
Log.d(TAG, "onNext:$it");
})
}
结果和刚才没什么区别,只有时间的区别,写法也大同小异。看到这里估计很多同学要骂人了,你不是说要简历被观察者吗,然后建立观察者对象吗,最后才建立订阅关系吗,我怎么没发现?大兄弟你消消气,听我慢慢说。其实观察仔细的都差不多明白了关系,不管是Flowable还是Observable都是通过subscribe建立了关系,并通过Consumer返回,这是一种简写方式,下面我们看一下常规写法,也就是上面说的,先建立被观察者对象在建立观察者对象,最后建立订阅关系。不多说,上代码。
Observable.create(ObservableOnSubscribe<String> {
var i = 0;
while (i < 10) {
it.onNext("数据$i")
Thread.sleep(1000)
i++
}
it.onComplete()
}).subscribe {
Log.d(TAG, "onNext:$it")
}
还是不明了?继续上代码
Observable.create(ObservableOnSubscribe<String> { emitter ->
try {
var i = 0
while (i < 10) {
emitter.onNext("数据$i")
Thread.sleep(1000)
i++
}
emitter.onComplete()
} catch (e: InterruptedException) {
Log.e(TAG, "onNext:${e.toString()} ")
}
}).subscribe(object : Observer<String> {
override fun onComplete() {
}
override fun onError(e: Throwable) {
}
override fun onNext(t: String) {
Log.d(TAG, "onNext:$t")
}
override fun onSubscribe(d: Disposable) {
}
})
看明白了吗?其实上面的都是简写形式,最后这个是大多数情况下会用到的全写方式。我慢慢介绍
Observable:被观察者对象
ObservableOnSubscribe:事件发射器
subscribe:订阅关系
Observer:观察者对象
大体就是Observable创建了一个对象,通过ObservableOnSubscribe发射器发送事件,然后通过subscribe和Observer建立订阅关系。我这里让线程沉睡一秒就是为了让数据更好的观察,因为写了两个所以会发送两次,你问为什么不是交错发送的,答案后面告诉你,仔细观察时间变化