一直以来,android开发者对于RxJava一直褒贬不一,有的人说RxJava好用,有人说不好用;但是作为一个有经验的开发者,RxJava的出现无疑是一个里程碑,RxJava其实还是很好用的;

那么 RxJava到底是什么呢?在github主页上有这样介绍:

RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.

其实,简单来说,RxJava就是一个异步的库;
但是相对于handler 和asyncTask而言,RxJava的优势就是简洁,功能强大;

下面介绍RxJava

1.RxJava的依赖

Rxjava中
被观察者Observable/观察者Subscriber/subscribe订阅

之后便是添加依赖:

compile 'io.reactivex:rxjava:1.3.0'
    compile 'io.reactivex:rxandroid:1.2.1'

2.RXJava的API详解(代码详解)

2.1被观察者的创建和订阅观察者完全回调mObservable.subscribe(new Subscriber()

//方法一
mObservable = Observable.create(new Observable.OnSubscribe<String>() {

            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("   hello");
                subscriber.onNext("   hi");
                subscriber.onNext("   你好");
                //subscriber.onCompleted("    so good");
            }
        });

//方法二
mObservable = Observable.just("   hello","   hi","   你好");

在上面代码中介绍了两种方法;
在创建过程中 对onNext中参数进行初始化,在之后被观察者订阅观察者时候重写onNext方法操作传入的参数;

即:

mObservable
            .subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {
                if (s != null || !s.equals("")) {

                    mTemp = mTemp + s;
                }


                mContent.setText(mTemp);
            }
        });

从上面代码中 可以看到 在订阅观察者的时候,重写onNext时 获取在创建被观察者的时候传入三个参数 然后进行操作;

2.2.订阅观察者的不完全回调,即在观察者中仅会调onNext的方法

下面 直接来看代码:

mObservable.subscribe(new Action1<String>() {

            @Override
            public void call(String s) {
                if (s != null || !s.equals("")) {

                    mTemp = mTemp + s;
                }


                mContent.setText(mTemp);
            }
        });

在这里 ActionX是RxJava中封装的接口 对应onNext方法 同时因为可以对应onCompleted() onError() :

public final Subscription subscribe
(final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onCompleted)

可以看到
当Action1参数为Throwable就是onError();
当Action1参数为除Throwable以外的其他类型的时候 代表onNext
Action0 代表onCompleted

2.3 map的使用
场景:数字字符串 输出数字相加的和:

private String[] mTarget = new String[]{"123456" };

   ......

   Observable.from(mTarget)
                .map(new Func1<String, Integer>() {

                    @Override
                    public Integer call(String s) {
                        int i = Integer.parseInt(s);

                        return i;
                    }
                })
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {

                        mContent.setText(integer + "");
                    }
                });

在上面代码中 首先Observable.from(mTarget)将字符串转化为

Observable<String>

然后利用map 将String类型转化为intenger类型 在订阅时候输出;

.map(new Func1<String, Integer>() {

                    @Override
                    public Integer call(String s) {
                        int i = Integer.parseInt(s);

                        return i;
                    }
                })

其中FuncX和ActionX一样是RxJava封装的接口,他们两个的区别在于:FuncX有返回值,而ActionX没有返回值

2.4 介绍到这里 有必要介绍一下flatMap

mObservable
                .flatMap(new Func1<String, Observable<String>>() {
                    @Override
                    public Observable<String> call(String s) {
                        return Observable.from(mTarget);
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {

                        Log.i("==Call",s);

                    }
                });

flatMap和 map其实一样都是在订阅之前 对参数的一个转化 ,不同的是map是一对一的转化;比如String转化为Intenger;而flatMap不同 是一对多;从上面代码可以看出来 flatMap将String转化为

Observable<String>

到这里RXJava 中基本常用的Api就介绍完了 ,有需求有兴趣的可以查阅官网进行补充;

3.RXJava中的控制器:Schedulers

既然涉及到异步 必然要设计到线程的控制:

Schedulers.immediate();在当前线程操作
Schedulers.newThread();总是启用新线程
Schedulers.io();在io线程中,一般处理耗时操作
AndroidSchedulers.mainThread();在主线程中,一般是更新ui

下面 看代码:

Observable.create(new Observable.OnSubscribe<Drawable>() {


            @Override
            public void call(Subscriber<? super Drawable> subscriber) {
                Drawable drawable = getResources().getDrawable(R.drawable.t2);
                subscriber.onNext(drawable);
                subscriber.onCompleted();
            }
        })
                .subscribeOn(Schedulers.io()) //Observable.OnSubscribe中Call方法所在线程
                .observeOn(AndroidSchedulers.mainThread())  //Subscribe中回调所在的线程
                .subscribe(new Subscriber<Drawable>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Drawable drawable) {

                        mBg.setImageDrawable(drawable);

                    }
                });

上面 代码就很明了了:
.subscribeOn(Schedulers.io()) //Observable.OnSubscribe中Call方法所在线程
.observeOn(AndroidSchedulers.mainThread()) //Subscribe中回调所在的线程

这样 耗时操作和更新ui就分配到了相应的线程 是不是很简便;

4.作为当下最好的网络框架retrofit有两套API 一套传统的callback 一套是RXJava 这里我们 对比着来看:

4.1准备工作
首先在retrofit使用rxjava对应api必须要添加依赖:

compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

    compile 'io.reactivex:rxjava:1.3.0'
    compile 'io.reactivex:rxandroid:1.2.1'

在创建retrofit对象时候,添加对应的callbackAdapter:

mRetrofit = new Retrofit.Builder()
      ......
      ......          .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

4.2网络请求回调
首先call是retrofit的代理类 即

mRetrofit = new Retrofit.Builder()
                .baseUrl("http://111.200.195.247:8003")
                .client(mOkhttpClient) //设置请求OkhhtpClient实例
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
mService = mRetrofit.create(ReponseInfoApi.class);
Observable<LoginInfo> info = mService.getInfo("APPAPI", "123456", code, data);

然后使用RxJava需要在注解类中加入Observable(xxx),eg:

@FormUrlEncoded
    @POST("/api/TimApi")
    Observable<LoginInfo> getInfo(@Field("name")String name, @Field("key")String key,
                                  @Field("code")String code, @Field("data")String data);

对比请求过程代码 来看下面代码中展示的是:

//传统callBack API
        call.enqueue(new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, retrofit2.Response<T> response) {
                mListener.onSuccess(response);
            }

            @Override
            public void onFailure(Call<T> call, Throwable t) {
                mListener.onFail(t);
            }
        });


        //RXJava
        call.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<T>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(T t) {

                    }
                });

上面 展示两套API (常用CallBack和RXJava) 可见RxJava 比较简便 ,为什么会这样呢 应为在retrofit中有rxjava的接口实现 有兴趣可以去看源码;