RxJava

RxJava是什么

RxJava是一种异步方式:类似于android中的AsyncTask 和Handler ,RxJava并不是一个”拿来就能用”的项目,他需要我们像学习门新语言一样从语法–>词汇–>用法的学习过程

作用是什么

用于:逻辑的简洁,并不是单纯的代码量少

RxJava 的使用

  1. 创建一个被观察者
Observable<String> myObservable = Observable.create(  
    new Observable.OnSubscribe<String>() {  
        @Override  
        public void call(Subscriber<? super String> sub) {  
            sub.onNext("Hello, world!");  
            sub.onCompleted();  //标记完成
        }  
    }  
);

2.创建一个Subscriber来处理Observable对象发出的字符串

Subscriber<String> mySubscriber = new Subscriber<String>() {  
    @Override  
    public void onNext(String s) { System.out.println(s); }  

    @Override  
    public void onCompleted() { }  

    @Override  
    public void onError(Throwable e) { }  
};

3.通过subscribe函数就可以将我们定义的myObservable对象和mySubscriber对象关联起来,这样就完成了subscriber对observable的订阅。

myObservable.subscribe(mySubscriber);//订阅

以上代码简化
RxJava 提供了很多简化创建Observable对象的方法
如:Observable.just(),用来创建只发出一个事件就结束的Observable对象

//创建Observable 简化代码
Observable<String> myObservable = Observable.just("Hello, world!");
//简化Subscriber,在Subscriber中我们关注的只有onNext 一个方法,这时候就可以使用Action1 类
    Action1<String> onNextAction = new Action1<String>(){
        @Override
        public void call(String s) {
            Log.e("onCompleted", s);
        }
    };
//订阅 subscribe方法有一个重载版本,接受三个Action1类型的参数,分别对应OnNext,OnComplete, OnError函数。
        //这里我们并不关心onError和onComplete,所以只需要第一个参数就可以
        myObservable.subscribe(onNextAction);

再简化

 Observable.just("Hello, world!")
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("call", s);
                    }
                });

错误处理

onComplete()和onError()函数。这两个函数用来通知订阅者,被观察的对象将停止发送数据以及为什么停止(成功的完成或者出错了)

RxJava 中的操作符

1. 操作符(map)

作用:操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件,就是用来把把一个事件转换为另一个事件的

案例:在hello world中加上我的签名,会想到要去修改被观察者,如果加上签名这个需求只针对于某个订阅者,那么去修改被观察者显然不行,这个时候就用到了map操作符,变换Observable对象

 Observable.just("Hello, world!")
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        return s + " RxJava";
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("call", s);
                    }
                });

改变数据类型的observable对象

Observable.just("Hello, world!")
                .map(new Func1<String, Integer>() {
                    @Override
                    public Integer call(String s) {
                        return s.hashCode();
                    }
                })
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.e("call", integer.toString());
                    }
                });

这里出现了一个叫做 Func1 的类。它和 Action1 非常相似,也是 RxJava 的一个接口,用于包装含有一个参数的方法。 另外,和 ActionX 一样, FuncX 也有多个,用于不同参数个数的方法。FuncX 和 ActionX 的区别在 FuncX 包装的是有返回值的方法。

  1. Observable和Subscriber可以做任何事情
    Observable可以是一个数据库查询,Subscriber用来显示查询结果;Observable可以是屏幕上的点击事件,Subscriber用来响应点击事件;Observable可以是一个网络请求,Subscriber用来显示请求结果。

  2. Observable和Subscriber是独立于中间的变换过程的。
    在Observable和Subscriber中间可以增减任何数量的map。整个系统是高度可组合的,操作数据是一个很简单的过程。

2.操作符from

操作数组或者集合中每个数据,不需要使用for 来遍历
Observable.from()方法,它接收一个集合作为输入,然后每次输出一个元素给subscriber:

案例:根据输入的字符串返回一个网站的url列表(搜索引擎)

 query("Hello, world!")
                .subscribe(new Action1<List<String>>() {
                    @Override
                    public void call(List<String> strings) {
                        for(String s:strings){
                            Log.e("call", s);
                        }
                    }
                });

使用from操作符

 query("Hello, world!")
                .subscribe(new Action1<List<String>>() {
                    @Override
                    public void call(List<String> strings) {
//                        for(String s:strings){
//                            Log.e("call", s);
//                        }

                        Observable.from(strings)
                                .subscribe(new Action1<String>() {
                                    @Override
                                    public void call(String s) {
                                        Log.e("call", s);
                                    }
                                });
                    }
                });

多个嵌套的subscription,进行修改

3.操作符(flatMap())

Observable.flatMap()接收一个Observable的输出作为输入,同时输出另外一个Observable

 query("Hello, world!")
                .flatMap(new Func1<List<String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(List<String> strings) {
                        return Observable.from(strings);
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("call", s);
                    }
                });

flatMap()可以返回任何它想返回的Observable对象。

4.操作符merge,合并观察者对象

 ArrayList<String> list1 = new ArrayList<String>();
        ArrayList<String> list2 = new ArrayList<String>();

        list1.add("1");
        list1.add("2");
        list1.add("3");

        list2.add("a");
        list2.add("b");
        list2.add("c");

        Observable mObservable1 = Observable.from(list1);
        Observable mObservable2 = Observable.from(list2);

        //合并数据  先发送observable2的全部数据,然后发送 observable1的全部数据
        Observable mObservable3 = Observable.merge(mObservable2, mObservable1);

        mObservable3.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("call3",o.toString());
            }
        });

5. 操作符zip

zip 操作符,合并多个观察对象的数据。并且允许 Func2()函数重新发送合并后的数据

ArrayList<String> list1 = new ArrayList<String>();
        ArrayList<String> list2 = new ArrayList<String>();

        list1.add("1");
        list1.add("2");
        list1.add("3");

        list2.add("a");
        list2.add("b");
        list2.add("c");

        Observable mObservable1 = Observable.from(list1);
        Observable mObservable2 = Observable.from(list2);

        //合并Observable数据 ,并重新发送组合后的数据
        Observable mObservable3 = Observable.zip(mObservable1, mObservable2, new Func2<String,String,String>() {

            @Override
            public String call(String s, String s2) {
                return s+s2;
            }
        });

        mObservable3.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("zip === ",o.toString());
            }
        });

6. scan累加器操作符的使用

 Observable mObservable = Observable.just(1, 2, 3, 4, 5);
        //返回相加结果
        Observable mObservableScan = mObservable.scan(new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer o, Integer o2) {
                return o + o2;
            }
        });

        mObservableScan.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("scan == ", o.toString());
            }
        });

打印结果

D/scan ==: 1
D/scan ==: 3
D/scan ==: 6
D/scan ==: 10
D/scan ==: 15

7. filter 过滤操作符的使用

满足结果才会发送

Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
        //过滤
        Observable mObservableFilter = mObservable.filter(new Func1<Integer,Boolean>() {
            @Override
            public Boolean call(Integer o) {
                //数据大于4的时候才会被发送
                return o > 4;
            }
        });

        mObservableFilter.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("filter == ", o.toString());
            }
        });

结果

D/filter ==: 5
D/filter ==: 6
D/filter ==: 7

8. 消息数量过滤操作符的使用

take :取前n个数据
takeLast:取后n个数据
first 只发送第一个数据
last 只发送最后一个数据
skip() 跳过前n个数据发送后面的数据
skipLast() 跳过最后n个数据,发送前面的数据

Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
        //take 发送前三个数据
        Observable mObservableTake = mObservable.take(3);

        mObservableTake.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("take == ", o.toString());
            }
        });

        //takeLast 发送后三个数据
        Observable mObservableTakeLast = mObservable.takeLast(3);
        mObservableTakeLast.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("takeLast",o.toString());
            }
        });

        //first 只发送第一个数据
        Observable mObservableFirst = mObservable.first();
        mObservableFirst.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("first === ",o.toString());
            }
        });

        //last 只发送最后一个数据
        Observable mObservableLast = mObservable.last();
        mObservableLast.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("last === ",o.toString());
            }
        });

        //skip 跳过前2个数据发送后面的数据
        Observable mObservableSkip = mObservable.skip(2);
        mObservableSkip.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("skip === ",o.toString());
            }
        });

        //skipLast 跳过最后2个数据发送后面的数据
        Observable mObservableSkipLast = mObservable.skipLast(2);
        mObservableSkipLast.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("skipLast === ",o.toString());
            }
        });

结果

D/take ==: 1
D/take ==: 2
D/take ==: 3
D/takeLast: 5
D/takeLast: 6
D/takeLast: 7
D/first ===: 1
D/last ===: 7
D/skip ===: 3
D/skip ===: 4
D/skip ===: 5
D/skip ===: 6
D/skip ===: 7
D/skipLast ===: 1
D/skipLast ===: 2
D/skipLast ===: 3
D/skipLast ===: 4
D/skipLast ===: 5

9. elementAt 、elementAtOrDefault

注意:elementAt() 发送数据序列中第n个数据 ,序列号从0开始,如果该序号大于数据序列中的最大序列号,则会抛出异常,程序崩溃,所以在用elementAt操作符的时候,要注意判断发送的数据序列号是否越界

Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
        Observable mObservableElementAt = mObservable.elementAt(2);
        mObservableElementAt.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("elementAt === ", o.toString());
            }
        });

//        elementAtOrDefault( int n , Object default ) 发送数据序列中第n个数据 ,序列号从0开始。
//        如果序列中没有该序列号,则发送默认值
        Observable mObservableElementAtOrDefault = mObservable.elementAtOrDefault(8,0);
        mObservableElementAtOrDefault.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("elementAtOrDefault === ",o.toString());
            }
        });

结果

D/elementAt ===: 3
D/elementAtOrDefault ===: 0

10.startWith() 插入数据
在已有数据之前插入数据,数据类型可以是普通类型和Observable 对象

 Observable mObservable = Observable.just("aa","bb","cc");
        Observable mObservableStartWith = mObservable.startWith("11", "22");
        mObservableStartWith.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("StartWith 插入普通数据", o.toString());
            }
        });


        //插入Observable对象
        ArrayList<String> list = new ArrayList<String>();
        list.add("ww");
        list.add("tt");

        mObservable.startWith(Observable.from(list))
                .subscribe(new Action1() {
                    @Override
                    public void call(Object o) {
                        Log.d("startWith 插入Observable 对象",o.toString());
                    }
                });

结果

D/StartWith 插入普通数据: 11
D/StartWith 插入普通数据: 22
D/StartWith 插入普通数据: aa
D/StartWith 插入普通数据: bb
D/StartWith 插入普通数据: cc
D/startWith 插入Observable 对象: ww
D/startWith 插入Observable 对象: tt
D/startWith 插入Observable 对象: aa
D/startWith 插入Observable 对象: bb
D/startWith 插入Observable 对象: cc

11.delay操作符,延迟数据发送

只限制第一条数据发送的时间

Observable mObservable = Observable.just("aa","bb","cc");
        //延迟数据发射的时间,仅仅延时一次,也就是发射第一个数据前延时。发射后面的数据不延时
        Observable mObservableDelay = mObservable.delay(2, TimeUnit.SECONDS);//延迟两秒发送
        mObservableDelay.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("delay ==", o.toString());
            }
        });

12. interval 轮询操作符,循环发送数据,数据从0开始递增

private Subscription mSubscription;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //参数一:延迟时间  参数二:间隔时间  参数三:时间颗粒度 MILLISECONDS 每秒一次
        Observable mObservable = Observable.interval(3000, 1000, TimeUnit.MILLISECONDS);
        mSubscription= mObservable.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("interval == ", o.toString());
            }
        });
    }
    //销毁的时候停止轮询
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mSubscription !=null){
            mSubscription.unsubscribe();
        }
    }

结果

D/interval ==: 0
D/interval ==: 1
D/interval ==: 2
D/interval ==: 3
D/interval ==: 4
D/interval ==: 5
D/interval ==: 6
D/interval ==: 7
D/interval ==: 8
I/[Gralloc]: gralloc_unregister_buffer line 259 size3686400 base0x603ef000 phys_addr0 share_fd55 usage0x900 ion_hnd_debug0x2
I/[Gralloc]: gralloc_unregister_buffer line 259 size3686400 base0x614d4000 phys_addr0 share_fd60 usage0x900 ion_hnd_debug0x7
D/interval ==: 9

13.doOnNext() 操作符,在每次 OnNext() 方法被调用前执行

Observable mObservable = Observable.just("1", "2", "3", "4");
        mObservable.doOnNext(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("doOnNext  call",o.toString());
            }
        }).subscribe(new Observer() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Object o) {
                Log.d("onNext",o.toString());
            }
        });

结果

D/doOnNext  call: 1
D/onNext: 1
D/doOnNext  call: 2
D/onNext: 2
D/doOnNext  call: 3
D/onNext: 3
D/doOnNext  call: 4
D/onNext: 4

14. throttleFirst 操作符

在一段时间内,只取第一个事件,然后其他事件都丢弃。

使用场景:1、button按钮防抖操作,防连续点击 2、百度关键词联想,在一段时间内只联想一次,防止频繁请求服务器

Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //使用interval 达到每秒发送一个,在3秒内只取一个事件,其他的丢失
        mSubscription = Observable.interval(1, TimeUnit.SECONDS)
                .throttleFirst(3, TimeUnit.SECONDS)
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        Log.d("throttleFirst == ", aLong.toString());
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mSubscription != null) {
            mSubscription.unsubscribe();
        }
    }

结果

D/throttleFirst ==: 0
D/throttleFirst ==: 4
D/throttleFirst ==: 7
D/throttleFirst ==: 10
D/throttleFirst ==: 13
D/throttleFirst ==: 16
D/throttleFirst ==: 19
D/throttleFirst ==: 22
D/throttleFirst ==: 25

15.distinct 过滤重复的数据

 ArrayList<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("1");
        list.add("3");
        list.add("4");
        list.add("2");
        list.add("2");
        list.add("1");

        Observable.from(list)
                .distinct()
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("distinct == ", s);
                    }
                });

结果

D/distinct ==: 1
D/distinct ==: 2
D/distinct ==: 3
D/distinct ==: 4

16. distinctUntilChanged() 过滤连续重复的数据

ArrayList<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("1");
        list.add("3");
        list.add("4");
        list.add("2");
        list.add("2");
        list.add("1");

        Observable.from(list)
                .distinct()
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("distinct == ", s);
                    }
                });

        Observable.from(list)
                .distinctUntilChanged()//过滤连续重复的数据
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("distinctUntilChange == ", s);
                    }
                });

结果

D/distinctUntilChanged ==: 1
D/distinctUntilChanged ==: 2
D/distinctUntilChanged ==: 1
D/distinctUntilChanged ==: 3
D/distinctUntilChanged ==: 4
D/distinctUntilChanged ==: 2
D/distinctUntilChanged ==: 1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章