RxJava的几个操作符和应用场景


RxJava简介:

可以使代码变的简洁,增加代码的可读性可维护性。

Observable.from(folders)
    .flatMap((Func1) (folder) -> { Observable.from(file.listFiles()) })
    .filter((Func1) (file) -> { file.getName().endsWith(".png") })
    .map((Func1) (file) -> { getBitmapFromFile(file) })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe((Action1) (bitmap) -> { imageCollectorView.addImage(bitmap) });


使用的是观察者模式,又叫订阅发布模式实现的。

传统的观察者模式:



观察者模式和订阅发布模式是一样的,观察者又叫订阅者,被观察者又叫发布者。



了解与传统的观察者模式区别,避免入坑:

1.在RxJava中这两种名字经常混用,所有要弄清楚谁是观察者(Observer)被观察者(Observable)订阅者(Subscriver)发布者(publisher 暂时没有见到),这也是RxJava容易对初学者造成的困惑。


2.RxJava中在subscrib()之后根据操作符来完成回调方法中的不同方式的响应,传统观察者是在订阅后处于等待的状态,待被观察者发布消息后再进行回调。



使用需要加入下面依赖包

compile'io.reactivex:rxjava:1.2.4'

compile'io.reactivex:rxandroid:1.2.1'




一、使用方法

1.创建被观察者:Observable     

2.创建观察者(订阅者):Observer (Subscriber)Observer与Subscriber是继承关系,实现细节不一样

3.订阅   subscribe()

4.订阅之前可以添加操作符,链式的结构

二、几个例子

第一个例子:使用步骤


  //步骤1:创建被观察者 除了使用from可以有其他多种方式
        Observable observable1=Observable.from(new String[]{"hello","hi","jcc"});
        //步骤2:创建观察者  也可以使用Observer Action1 Action2等
        Subscriber<String> subscribe=new Subscriber<String>() {

            @Override
            public void onStart() {
                super.onStart();
                Log.i("jcc","method1 onStart");
            }

            @Override
            public void onCompleted() {
                Log.i("jcc","method1 onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.i("jcc","method1 onError"+e.getMessage());
            }

            @Override
            public void onNext(String s) {
                Log.i("jcc","method1 onNext "+s);
            }
        };
        //步骤3:订阅
        observable1.subscribe(subscribe);

   这是一个最简单的使用例子,实现一次打印String数组中字符串。subscribe之后根据需要回调其中的回到方法,很容易根据名字来判断回到顺序,onStart(),onNext(),onComplete()为正常顺序,onError()为异常时调用。

以上是默认的回调顺序,Observable提供create操作符来创建新的Observable自定义回调。也可以使用RxJava库提供的一些类Action1等。

这里只是最简单的实现,后面的编程都是根据 obServable1.subscribe(subscribe)的扩展,或者说所有的RxJava响应式编程的结构都是Obserable.subscribe(Subscriber)这么一个链的扩展。

Obserable .创建操作符(参数)  //创建操作符有just、create、from等

.操作符1(参数)

.操作符2(参数)

...

.操作符n(参数)

.subscribe(subscriber);


参数可以是一个匿名内部类。

操作符的属相非常多,数量多说明可以实现的功能也就非常的庞大,我这里写的几个只能算入门级的。


第二个例子:线程的切换(subscribeOn observeOn操作符的使用 )



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

            @Override
            public void call(Subscriber<? super Drawable> subscriber) {
                Log.i("jcc",Thread.currentThread().getName());
                //运行在subscribeOn()操作符设置的线程
                 Drawable  drawable=getTheme().getDrawable(drawalbe);
                subscriber.onNext(drawable);
                subscriber.onCompleted();
            }
        })
        .subscribeOn(Schedulers.io())//被观察者的回调运行的线程
        .observeOn(AndroidSchedulers.mainThread())//观察者的回调运行的线程
        .subscribe(new Observer<Drawable>() {
                @Override
                public void onCompleted() {     
                }

                @Override
                public void onError(Throwable e) {
                }

                @Override
                public void onNext(Drawable drawable) {
                    //运行在sbuscribeOn设置的线程
                    ((ImageView)findViewById(R.id.iv)).setImageDrawable(drawable);
                }
        });



这里使用的是一个例子实现的是类似于Handler或者AsyncTask的异步过程,在工作线程中加载资源文件(当然也可以换做网络请求),在主线程中set图片。


第三个例子:Retrofit结合RxJava做网络请求框架

Retrofit是对Okhttp的封装,将请求返回的io流转化为Retrofit的Servcie接口,再通过Gson解析到实体类。

Retrofit中本身不使用RxJava,retrofit的addCallAdatperFactorty()中传入RxJavaCallAdapterFactory.Create()后,异步调用接口可以转化为RxJava的模式,进而使用RxJava的各种操作符。

以下是一个使用Okhttp+Retrofit+RxJava获取百度天气的一个例子

//创建Retrofit
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(WEATHERAPI)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
	//RxJavaServcie是按照Retrofit格式创建的一个接口,用于将网络数据转化为实体类
        RxJavaService service=retrofit.create(RxJavaService.class);
        service.getServiceOfRx(
                "北京",
                "json",
                "MymckXimfSdyGCmtlqbMoplcqibZtzdu",
                "77:BD:E8:C4:B1:28:5A:26:8B:E8:F1:C0:CE:45:40:E1:E4:A1:12:FE;jiacc.justhabit"
        ).subscribeOn(Schedulers.io())
         .observeOn(AndroidSchedulers.mainThread())
         .subscribe(new Subscriber<Weather>() {
             @Override
             public void onCompleted() {
             }

             @Override
             public void onError(Throwable e) {
             }

             @Override
             public void onNext(Weather weather) {
                 Weather.WeatherData data=weather.results.get(0).weather_data.get(0);
                 Picasso.with(mContext).load(data.dayPictureUrl).into(iv);
                 tv_weathers.setText(data.weather+" "+data.wind+" "+data.temperature);
                 tv_date.setText(data.date);
             }
         });

第四个例子:转换(Map操作符的使用)

//students的类型是List<Student> 
Observable.from(students)
                .map(new Func1<Student, String>() {//使用map依次将List的每个对象在回调方法中转为为student.name
                    @Override
                    public String call(Student student) {
                        return student.name;
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i("jcc",s);
                    }
                });


以上是一对一的转换,当一个学生有多门课程的时候,

 Observable.from(students)
                .flatMap(new Func1<Student, Observable<String>>() {
                    @Override
                    public Observable<String> call(Student student) {
                        return Observable.from((String[])student.courses);
                    }
                })
                .subscribe(new Observer<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i("jcc",e.getMessage());
                    }

                    @Override
                    public void onNext(String s) {
                        Log.i("jcc",s);
                    }
                });

第五个例子:RxJava代替EventBus进行数据传递:RxBus


IM举例来说,服务器推送来消息,更新消息的方法有如下几个:

1. 只更新当前页面,如有其他页面在onCreate()的时候传入值更新
2. 设置广播事件。来消息的时候发送广播提示更新
3. 设置接口。
4. 使用观察者模式。也就是Eventbus以及Rxbus实现的功能,或者java中的Observable

上面的四种方式,

第一种差评,可以直接排除。

第二种,每条消息都要创建Intent,频繁的发广播

第三种,新房帮以前的就是类似这样做的,每个需要更新的页面都有一个refresh()方法,维护起来十分麻烦(这种也是最原始的观察者模式了,只是没有使用API那么好用)

因此,在这里就可以使用Eventbus或者Rxbus了。

http://blog.csdn.net/liuye066/article/details/53924957




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值