前言:从零开始学习RxJava,首先是现在才来学习确实已经比别人慢了很多了,没办法,还是要学呀。RxJava只是响应式编程中的一种,还有其他语言的,这些简介啥的只有去官网看了,响应式编程的优点也不说了,我也不想清楚,知道流弊就行了,懂怎么用,适用于哪些情况再说去研究其他的吧。
1、RxJava基本概念和使用场景
2、RxJava创建观察者和被观察者
3、快速创建观察者和被观察者的方式
4、模仿一个retrofit进行网络访问
5、一些简单的操作符
效果图:
1、什么是RxJava?
我现在接触的rxjava,它就像我们设置onclick监听器一样,一个按钮被设置监听器,当它被按下的时候它就调用监听器的方法,于是就实现了按钮和监听器直接的通信。rxjava的用法类似,但是它的概念是观察者(监听器)和被观察者(按钮),现在暂时了解这么多吧,用到rxjava的其它功能,也就越来越了解它了。
1.1、RxJava中最基本的三个类
Observer :观察员
Subscriber:订阅者
Observable:观察得到的(被观察者)
来自百度翻译,刚刚接触确实看着不舒服,适应适应就好。Observer 与Subscriber的区别,其实他们是一个概念,观察员和订阅者不是都是想要实时得到被观察者的变化吗?从源码看出Subscriber是一个抽象类,而且是Observer 的子类,并且实现了一个接口Subscription(用于撤销订阅关系),Subscriber多了一个onstart方法,类似于asycntask中pre方法一样,再被观察者通知观察者之前被调用。
1.2、RxJava使用场景
rxjava是一种观察者模式,那么具体应用的最多的就是多线程,比如网络请求,类似于asynctask。rxjava中,可以自己切换线程,默认情况下,订阅过程和订阅的回调都发生在调用订阅的线程中,可以根据具体业务指定订阅过程和订阅回调发生在不同的线程中。(稍后再了解)
2、创建观察者Observer
//创建一个观察者 Observer<String> observer = new Observer<String>() { @Override public void onNext(String s) { Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { Toast.makeText(MainActivity.this,"报错",Toast.LENGTH_SHORT).show(); } };
2.1、创建观察者Subscriber
Subscriber<String> subscriber = new Subscriber<String>() { @Override public void onStart() {//可以选择重写或者不重写 super.onStart(); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(String s) { } };这里放着这两个类,他们几乎一样的,但是由于Subscriber多了onstart方法和实现了一个 用于撤销的接口Subscription,所以显然Subscriber更适用,在订阅的时候我们传递的也是它,如果传递Observer 会被转型成Subscriber
2.2创建被观察者
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { } });2.3、发生订阅关系
observable.subscribe(observer);
这个时候,相当于已经给button设置了onclick事件,现在我们就要模拟一个类似点击事件,让被观察者通知观察者,于是在观察者的call方法中,调用:
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("被观察者返回值了"); subscriber.onError(new Throwable("被观察者报错了")); subscriber.onCompleted(); } });
这个时候观察者的onNext方法就会被调用了,当然还有对应的onError和onCompleted,onError和onCompleted之间是互斥的,即,发生了错误就不会发生完成,发生了完成就不发生错误,onCompleted调用之后,再也不能发生onNext了。
现在,观察者和被观察者之间就发生了一次通信。目前为止我们需要了解到,观察者和被观察者怎么创建,如何订阅,被观察者在哪里回调观察者这三个知识点。
3、快速实现观察者和被观察者,利用rxjava的api,比如有时候我们的观察者只关心onNext事件,或者onNext和onError事件等,被观察者想直接发送一个或者多个事件出去。
3.1快速创建观察者,因为被观察者的订阅方法有多个重载,可以传递不完整观察者对象,用action来组合
public final Subscription subscribe(final Action1<? super T> onNext) {
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError)
所以这里我们创建一个action来用一下就行了,其他的也就是一样的了
Action1 action1 = new Action1() { @Override public void call(Object o) { } }; observable.subscribe(action1);注意这里的Action的call方法不是被观察者的call方法,这里是和观察者一样类似onNext方法回调,千万不要搞混了。
3.2快速创建被观察者,快速发送一个或者多个事件出去
Observable.just("事件1").subscribe(observer); Observable.just("事件1","事件2").subscribe(observer); Observable.just("事件1","事件2","事件3").subscribe(observer); Observable.from(new String[]{"事件1","事件2","事件3"}).subscribe(observer);
4、模仿一个retrofit框架请求,retrofit通过传递类,返回类的所有方法的返回值是一个被观察者
public class HttpUtil { private static HttpUtil httpUtil; private OkHttpClient okHttpClient; private HttpUtil(){ okHttpClient = new OkHttpClient(); } public static HttpUtil getInstance(){ if(null==httpUtil){ synchronized (HttpUtil.class){ if(null==httpUtil){ httpUtil = new HttpUtil(); } } } return httpUtil; } public Observable<String> doGet(final String url){ Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(final Subscriber<? super String> subscriber) { Request request =new Request.Builder().url(url).build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { subscriber.onError(new Throwable("网络错误")); } @Override public void onResponse(Call call, Response response) throws IOException { subscriber.onNext(response.body().string()); } }); } }); return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()); }
observable.subscribeOn(Schedulers.io())//订阅过程发生在io子线程中
observeOn(AndroidSchedulers.mainThread());//订阅回调发生在UI线程中
在调用出,new一个观察者,将被观察者订阅在一起,就可以通信了。操作符map等下一节。。。
HttpUtil.getInstance().doGet("http://www.baidu.com").subscribe(new Subscriber<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { tv.setText(e.getMessage()); Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show(); } @Override public void onNext(String s) { tv.setText(s); Toast.makeText(MainActivity.this,"访问成功",Toast.LENGTH_SHORT).show(); } });