本文参照、部分引用:
给 Android 开发者的 RxJava 详解 http://gank.io/post/560e15be2dca930e00da1083
大头鬼----深入浅出RxJAVA http://blog.csdn.net/lzyzsd/article/details/41833541
RXJava 到底是什么
RXjava类似观察者模式,可以实现不同模块之间的绑定、监听、响应,一点不同的是:在观察者模式中,无论一个被观察的主题中,是否有观察者,这个主题都会去执行自己的逻辑,并发出事件。而在RXJava中,如果没有Observer,那么Observable是不会发出任何事件的。
RXJava提供了一个框架,使得我们更方便的进行模块间,代码不同层次间的调用与监听,并提供强大的操作符,完成逻辑中各种常见的类型转换、状态搜集、运行线程的切换等操作。
RXJava中我认为最重要、最核心的东西就是Observer和Observable。其中我们自己实现的Observer用来实现各种响应事件,Observable用来处理业务逻辑并向订阅者分发事件。
RXJava采用链式编程,使得逻辑更清晰,便于阅读维护。
创建Subsriber
observer是一个接口,这个接口用来处理响应时间(回调事件)。Subscriber是一个实现了observer的抽象类。在使用中,我们直接使用Subscriber就可以了。
observer中主要有三个方法,这三个方法既Observer为了响应Observable发出的事件而实现的回调方法。
- onNext:触发普通回调,在一个事务观察过程中,可以触发多次onNext。
- onComplete:当事件队列结束时触发的方法,也就是被观察的事务结束的时候会调用这个方法,这个方法被调用意味着事物结束。
- onError:当被观察的事务执行过程中遇到异常的时候,会调用onError,onError同样只能被调用一次。注意,onError和onComplete是互斥的,在一个事物执行过程中,只能被调用一个。
Subsriber是在observer接口基础上封装的一个抽象类,在这里,增加了两个方法onStart和unSubsribe.
- onStart:在事件分发前调用,可以用来做一些准备工作,需要注意的是,onStart总在subscribe(既发生订阅动作)的线程中执行,所以需要对UI操作的时候要注意(需要更新UI可以使用doOnSubscribe)方法代替。
- unSubsribe:用来注销订阅,在调用unSubsribe这个方法后subsriber将不再接受任何事件。在调用这个方法前要用isUnsubsribe()来判断下是否已经注销。这个方法一定要在合适的地方及时调用,否则有内存泄露的风险。因为在subscribe后,observable总是持有着subscriber的引用。
创建subscriber的代码如下:
Subscriber<T> subscriber = new Subscriber<T>()
{
@Override public void onCompleted()
{
Log.d("test","onCompleted");
}
@Override public void onError(Throwable e)
{
Log.d("test","onError");
}
@Override public void onNext(T t)
{
Log.d("test","onNext");
}
};
创建Observable
observable既被观察的对象,这里边决定了什么时候触发什么事件。
Observable observable = Observable.create(new Observable.OnSubscribe<T>()
{
@Override public void call(Subscriber<? super T> subscriber)
{
T t = null;
try
{
subscriber.onNext(t);
subscriber.onNext(t);
subscriber.onCompleted();
}
catch (Exception e)
{
subscriber.onError(e);
}
}
});
创建Observable的时候传入一个OnSubsribe对象,这个对象会被保存在observable对象中。当observable被订阅的时候,OnSubscribe中的call方法将被调用。call中可以存放业务逻辑,并在合适的时候回调订阅者subsriber。
订阅
这一步是要将subscriber和observable联结起来。使其可以正常工作。
observable.subscribe(subscriber);
一些更简洁的使用方法
just(T....)
如果现在我们有三个同事的名字,需要在observable中获取,然后在subscriber中打印出来,正常情况下会这么做:
Subscriber<String> subscriber = new Subscriber<String>()
{
@Override public void onCompleted()
{
Log.d("test","onCompleted");
}
@Override public void onError(Throwable e)
{
Log.d("test","onError");
}
@Override public void onNext(String t)
{
Log.d("test","name is " + t);
}
};
Observable observable = Observable.create(new Observable.OnSubscribe<String>()
{
@Override public void call(Subscriber<? super String> subscriber)
{
try
{
subscriber.onNext("张三");
subscriber.onNext("李四");
subscriber.onNext("王五");
subscriber.onCompleted();
}
catch (Exception e)
{
subscriber.onError(e);
}
}
});
observable.subscribe(subscriber);
这实在是太麻烦了,传几个字符串而已,不用这么大张旗鼓吧,这里为了使代码更简洁,可以使用Observable的just方法来简化Observable的创建。just方法重载了一堆泛型参数为入参的方法,just(T t1,T t2,T t3......)。t1、t2、t3会依次通过onNext方法传入subscriber中。以上的例子就可以这样写:
Observable just = Observable.just("张三","李四","王五");
just.subscribe(subscriber);
just可以接受不同类型的入参,如果我想把张三的姓名、年龄、身高(String,int,float)传给subscriber:
Observable just1 = Observable.just("张三",30,1.83);
from(T[])
当使用just方法要传递的值过多的时候,我们可能会需要一个更方便的方法,直接放入一个数组或是迭代器,然后逐个元素发送,这时候就可以用到from啦!
String[] names = new String[]{"张三","李四","王五"};
Observable from = Observable.from(names);
from.subscribe(subscriber);
这段代码和上面是等价的。
actionX和funcX
ActionX和FuncX都是RXJava封装的好的接口,他们都在接口中定义了一个叫call的方法,所不同的是,actionX定义的方法中都没有返回值,或者说是返回的类型都为void。而funcX中定义的方法中有返回值。
再说说X是什么意思,X代表着call方法入参的数量,Action1代表着Action1接口中定义了一个void call(T t1)的方法,Action2中定义了一个void call(T t1,S s2)....在funcX中同理,Func1中定义了R call(T t1)的方法。。。。。
那这俩玩楞是干什么用的呢?
Action主要可以用来简化subscriber,如果在上面的例子中,我们要使用RXJava的话,首先要创建subsrcber,然后创建observable,最后订阅到一起。这一点都不简洁,一点都不链式好不好。。。
而且,我只想关注onNext,根本不想鸟onComplete或者是onError,OK~ subscribe这个神奇的方法定义了不同入参来满足这个需求:
一个只有OnNext入参的subscribe方法
public final Subscription subscribe(final Action1<? super T> onNext)
一个有OnNext和onError入参的subscribe方法
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError)
一个同时具有onNext、onError、onComplete入参的subscribe方法
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onComplete)
看到没有,我们在订阅的时候可以把subscrber抛到一边拉,可以直接用不同的Action来实现subscriber的功能,在这里,当运行到next的时候就会调用第一个Action,而且注意下 Action1和Action0的使用是因为onNext和onError方法都是一个入参,而onComplete没有入参。
Observable.just("张三","李四","王五").subscribe(new Action1<String>()
{
@Override public void call(String s)
{
Log.d("name",s);
}
});
所以刚才打印名字的那段代码如果写成这样是不是逼格更高了一些?
funcX具体的使用方式就要结合操作符啦! 等学习到操作符的时候会有func的例子哈 !