大概一年前就炒很火的Rxjava,本人也蹭热点上去学了两个月。学习坡度很高,整个过程也不是那么的顺利,再加上项目组很少有人用这个东西,所以把RxJava就搁置了。如果你问我RxJava好不好,答案一定是很好,但是它不是那么好上手,RxJava作用正如它的特点1, 异步 2. 基于观察者模式的函数式链式编程。如果能对设计模式有一定认识就已经很厉害了,大多数接触一两年Java这两部分都不会接触的很深。最近换了一家新公司,所以项目目前不是很忙的情况下,还要整改之前的老项目,在写代码的时候突然想到了之前的Rxjava。经过两年多的积累,感觉是时候引入Rxjava技术,Rxjava无意是最好的工具,很多的框架都使用它。
核心概念
Rxjava中最重要的两个概念便是Observables和Subscribers,如果你对观察者模式很熟悉,那么你可以对应理解为被观察者和观察者。它们两者之间的关系为Observables发送数据,Subscribers对应着处理数据。
问题在于数据在这两者之间是如何传递的,一个Observables可以发送任意的数据(包括空数据),然后它可以决定数据是否成功发送完成或者失败。对每一个Subscribers,一个Observable都会调用Subscriber.onNext()很多次,接下来伴随Subscriber.onComplete()或者Subscriber.onError()。
Observable一般不会立马发送数据直到有人订阅它们,在Rxjava中分为hot与cold Observable。两者的区别在于hot Observable会立刻发送数据,而cold Observable则会在subscriber注册时才会,如果是刚接触Rxjava暂时接触不到Hot Observable。文章下面的例子都是cold Observable。
开始 我们先简单写一个完整的Observale
Observable<String> observable = Observable.create(
new Observable.OnSubscribe<String>(){
public void call(Subscriber<? super String> sub){
sub.onNext("Hello world");
sub.onCompleted();
}
}
)
在我刚开始学习的时候,眼高手低觉得这么简单的东西,所以懒得看,可是人浮躁的话,到后来发现很多时候连基本的概念都没有搞清楚,走了很多的弯路。
上面的代码,我们如果以后工程上肯定不会这儿写,但是这是RxJava最核心概念,因为它从代码基本解释了RxJava是如何运行的。一个Observable对象通过Observable.create静态方法创建的,在create方法的参数中我们传入了一个对象Observable.OnSubscribe,并复写了call方法,通过Subscriber对象 sub调用了onNext()和onCompleted()方法。可能很多新手看到这里早就晕了,我当时在学习的时候也是如此,不过不懂可以放着但是一定要把这段代码记住。
上面这段代码只是简单做了一件事 便是输出『Hello world』 然后结束。接下来我们便创建一个Subscriber来消费这个数据:
Subscriber<String> mySubscriber = new Subscriber<String>() {
@Override
public void onNext(String s) { System.out.println(s); }
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
};
这段代码相对第一个段代码简单很多,无非创建了一个匿名对象 复写了Subscriber中的onNext方法并将字符串S打印出来。最后,我们已经有了一个Observable和一个SubScriber对象,现在我们要将两者连接起来使用subscribe():
observable.subscribe(mySubscriber)
当subscription建立起来,observable便会调用Subscriber的onNext方法 然后调用onComplete()方法,作为结果,mySubscriber输出『Hello World』。这便是Rxjava的最为核心的概念,如果你已经很熟悉了这个流程。恭喜你已基本掌握Rxjava。
简练代码
很多萌新看到这估计早炸锅了,就打印一句 helloworld 居然要写这么长的代码。其实上面只是完整展示Rxjava的工作流程,在工作中Rxjava提供了很多的简便方法来提供我们简化,看到后面你可能会被简练的代码所惊到。我们所是使用到的第一个方法便是Observable.just(),一行代码便完成第一段代码
Observable<String> observable = Observable.just("Hello world");
接下来我们简化Subscriber的方法,因为我们只关注onNext()方法,并不在乎
onCompleted()或者onError(),所有我们使用Action1来简化Subscriber
Action1<String> onNextAction = new Action1<String>() {
@Override
public void call(String s) {
System.out.println(s);
}
};
Actions可以定义Subscriber中的三种方法 onNext() onError() onComplete(),所以我们之前的代码其实是这样的
myObservable.subscribe(onNextAction,onErrorAction,onCompleteAction);
最后我们得到的代码如下
Observablel.just("Hello world").subscribe(new Action1<String>(){
public void call(String s){
System.out.println(a);
}
});
最后我们可以使用JAVA 8 lambdas来摆脱这又臭又长的Actions代码。
Observable.just("Hello world").subscribe(s ->System.out.println(s));
目前在我写作的时候,Android才刚刚原生支持Java8,但是之前我们也可以使用JAVA 8 lambdas,主要是使用retrolambda这个插件来实现的。
转化数据
Rxjava让人又爱又恨的便是它那支持函数式链式编程,如果你不太了解函数式编程,可以提前搜索一下。如果现在我们想要在Hello world中加上我的名字怎么办呢
Observable.just("Hello world! finch").subscribe(s -> System.out.println(s));
但是我们在Rxjava却不会这么使用 因为一般来讲我们没法确认Observable数据来源,所以我们想到的是便是在subscribe中修改发送过来的数据
Observable.just("Hello world!").subscribe(s -> System.out.println(s + "finch"));
但是这么使用仍然不是Rxjava的最佳姿势,理由如下: 1. 我们在subscribe中通常是在Android的主线程操作,所以我们要做的操作要尽可能的轻 2. 从Rxjava的设计概念来讲,Subscribers的作为更多体现在对数据做出响应中,而不是对数据做出修改的操作。 最佳的使用姿势便是在Observable和Subscriber中插入中间件
介绍操作符
对于操作符,所有学习编程语言的人再熟悉不过了,在RxJava中也存在操作符,操作符用在 源Observable 和最后Subscriber之间来操作发射中的数据。Rxjava中有海量的操作符,但是我们刚学习时最好专注一少部分。
为了解决上面的问题,我们引进第一个操作符map,map的作用在与将发射的数据转换为另外一个数据:
Observable.just("Hello, world!")
.map(new Func1<String, String>() {
@Override
public String call(String s) {
return s + " -Dan";
}
})
.subscribe(s -> System.out.println(s));
再一次我们使用lambda来简化代码
Observable.just("Hello world").map(s -> s + "finch").subscribe(s -> System.out.println(s));
是不是很简练,厉害的来了,我们可以在Observable和Subscriber中插入无数map操作符来将数据随心所欲的处理。
更多关于map()
在实际编程中Map可以说是相当的好用,但是map很有意思的一点在于,它可以从源数据Observable转换不同类型的数据。
Observable.just("Hello world")
.map(new Func1<String,Integer>(){
public Integer call(String s){
return s.hashCode();
}
}).subscribe(i ->System.out.println(integer.toString()));
是不是感觉很神奇 我们的数据源是一个字符串然后我将它转换为整数。
按照惯例我们将代码使用Lambda来简化
Observable.just("Hello world")
.map(s ->s.hashCode())
.subscribe(i -> System.out.println(Integer.toString()));
然而起始我们可以将其中再加入好几个Map操作来完成我们需要的操作
Observable.just("Hello world")
.map(s -> s + "-Dan")
.map(s ->s.hashCode())
.map(i _>Integer.toString(i))
.subscriber(s -> System.out.println(s));
到了这也许你可能对Rxjava已经有了一定的了解了,说不定你可能已经嘀咕了 你这操作可能也没什么了不起。不过看到这里想必你也能理解两点
-
Observable和Subscriber可以做任何事
因为Rxjava不像网络请求框架okhttp或者glide之类拿到就可以用,它更像一个灵活锋利的瑞士军刀,使用需要你发挥想象力,但是在下一章讲到Android异步编程中的线程调度功能,可能你就感觉离不开它了,因为实在是太好用了。
-
Observable和Subscriber在 数据的转换过程中是相对独立
我们可以在源Observable和Subscriber中可以穿插无数map操作符,所以这整个过程是高度的灵活,在一个合适方法链中,我们可以很好的操作输入输出的数据
光靠这两点,我们就可以看到这套系统的威力,实际上已经有很多的项目开源拿Rxjava来写 比如RxBus,在下一章我们将跳进更多的操作符池中,来更好的学习Rxjava
网友评论