RxJava 是reactiveX世界里面的一员,除了Rxjava,还有RxSwift,RxJs,RxRuby,Rx.net等等。在和RxJava 说hello之前,先说下观察者模式。观察者模式的原理就是,被观察的对象,持有观察者的实例,当被观察者发生了什么事情后,就调用它持有的观察者对象的方法。这样观察者就可以即使获取到通知啦。Ok,观察者模式讲完啦。开始Rxjava。
------------------------------------------------------------------------------杨幂的事业线------------------------------------------------------------------------------
开始RxJava:一个最简单的示例:
//定义一个观察者
Observer<String> observer = new Observer<String>() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "completed", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(String s) {
Log.d("Tag", s);
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
};
//创建一个被观察者
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("hello world!");
subscriber.onNext("hello world too!");
//subscriber.onError(new Throwable("出错了"));
subscriber.onCompleted();
}
});
//订阅
observable.subscribe(observer);
代码如下:
Observable observable=Observable.just("hello,world");
订阅后,我们的观察者就会打印出"hello,world"。
观察者同样有比较简洁的写法,如果你不关心onCompleted(),和onError()的话。事件流除了可以订阅一个obserber之外。还可以订阅Acition1对象。这个是什么鬼。先看下代码:
observable.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("Tag", s);
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
});
Action是Rxjava里面的接口,可以是Action0,Action1,Aciton2.......它里面有一个方法Call方法,该方法无返回值。如果是Aciton0,则call()方法无参数,如果是Aciton1则有一个参数,以此类推。我们的onNext(object)方法有一个参数,所有可以用Action1对象,去把我们的onNext(Objct)打包,给subscribe()方法。同样我们可以用Action0对象去打包onCompleted()方法,把它交给subscribe()方法。所以我们可以从代码提示中看到subscribe()方法除了可以接收一个obserber对象之外,还有其他三个重载方法。
// 自动创建 Subscriber ,并使用 onNextAction 来定义 onNext()
observable.subscribe(onNextAction);
// 自动创建 Subscriber ,并使用 onNextAction 和 onErrorAction 来定义 onNext() 和 onError()
observable.subscribe(onNextAction, onErrorAction);
// 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 来定义 onNext()、 onError() 和 onCompleted()
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
好了,如果Aciton这个类似于闭包的东西,没有让你晕的话,我们可以看下完整的代码:
Observable.just("hello,world").subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("Tag", s);
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
});
这段代码基本上等价最开始的一个示例代码。只是少了onCompleted(),和onError();当然我们可以加上,刚好再理解下Acition的用法。代码如下:
Observable.just("hello,world").subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("Tag", s);
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
Toast.makeText(MainActivity.this, throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
}, new Action0() {
@Override
public void call() {
Toast.makeText(MainActivity.this, "completed", Toast.LENGTH_SHORT).show();
}
});
三个参数的subscribe()方法,就相当于完整订阅了。功能就跟最上面那坨代码一样一样的。
到这里我们还是没看出来RxJava有什么作用,或者什么优势,显示一个Toast干嘛这么麻烦?Ok,想象一下,如果我们要订阅的东西,它比较耗时,我们不能再主线程中执行订阅的代码,然后我们还得在主线程去观察结果。这个时候脑子里开始闪现 AsyncTask / Handler /Thread......然后是线程间通信,然后就想说,辣鸡Android。我们先模拟一个耗时的操作。
//定义一个观察者
Observer<String> observer = new Observer<String>() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "completed", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(String s) {
Log.d("Tag", s);
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
};
//创建一个被观察者
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
subscriber.onNext("hello world!");
subscriber.onCompleted();
}
});
//订阅
observable.subscribe(observer);
好吧,希望到这里你已经知道上面代码是什么意思。他跟我们的第一段代码差不多,只是在被观察者的call方法里执行onNext()操作通知观察者时,我们停留了20秒。如果你看懂上面这段代码,并且在Android的主线程中运行, 你应该了解会发生什么事情。恩,ANR!
我们订阅的东东太耗时,20秒,这在现实的场景就类似于,我们订阅的东西,是从网络获取的数据,从数据库获取的数据,经过大量的复杂的数据运算获取到的数据。那么RxJava该如果解决呢?我们只要把订阅的那句代码改为如下:
observable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
subscribeOn()指定事件流发生的线程,observeOn()指定观察所在的线程。这样就可以很轻松的实现异步啦。subscribeOn()和observeOn()被称为Rx的调度器,有了这两个东西,我们就可以随意切换线程。优雅的实现异步操作。而且从这段代码可以发现,Rxjava的操作是链式调用的,一条线下来的。以后我们会有更复杂的操作,数据的各种变化,你会发现不管逻辑多复杂,它依然保持一条线下来。
----------------------------------------------------------------------柳岩的事业线---------------------------------------------------------------------------
上面有提到一个东西just(),这个是RxJava的一个操作符,他可以创建出一个事件流(Observab)。除了just()操作符外Rxjava还有很多很多的操作符。有创建类的操作符:如just、from、interval、rang、defer等;有变换类操作符如bufer、window、map、cast、flatMap、scan等;有过滤类操作符如throttle、debounce、distinct、elementAt、sample等;有组合类操作符combin、concat、merge、zip等。这许许多多的操作符让RxJava变得非常强大。可以应付各种各样复杂的情况。后面有时间说呗。先给几个介绍Rxjava的文章:
扔物线的:给Android开发者的RxJava详解,必看:
http://gank.io/post/560e15be2dca930e00da1083
大头鬼的深入浅出系列,必看:
http://blog.csdn.net/lzyzsd/article/category/2767743
RxJava Essentials中文翻译版:
源码地址:https://github.com/dagaozi/RxjavaDemo