Android-RxJava 常见API使用以及线程转换要点

什么是RxJava?RxJava 在 GitHub上的自我介绍是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava。

接下来不多说什么了,直接进入今天的主题吧

一.API使用

RxJava的API使用,包括Observable的创建,以及变换,以及数据的过滤等

1.Observable创建

Observable的创建有几种方式,比如create,just,from,interval,timer

1.1 create方法,是Rxjava中创建Observable最基本的方法,例子如下-创建Observable时,传入onSubsribe作为参数,会被存储在Observable对象中,当Observable被订阅时,就会触发其call方法。

private void testRxMethod_create() {
        Observable observable = Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscribersuper RxBeanInfo> subscriber) {
                RxBeanInfo info = new RxBeanInfo();
                info.setName("lqm.test");
                subscriber.onNext(info);
                subscriber.onCompleted();
            }});
        Subscriber subscriber = new Subscriber()
        {
            @Override
            public void onCompleted() {
                Log.i("rxjava", "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.i("rxjava", "error");
            }
            @Override
            public void onNext(RxBeanInfo o) {
                Log.i("rxjava", o.getName());
            }};
        //通过调用subscribe方法使观察者和订阅者产生关联,一旦订阅,Observable就会调用call().
        observable.subscribe(subscriber);
    }
11-17 14:27:14.513 14944-14944/pa.test.com.testapp I/rxjava: lqm.test
11-17 14:27:14.513 14944-14944/pa.test.com.testapp I/rxjava: onCompleted

1.2.just—通过调用just方法,传入你想发送的数据源,当订阅者进行订阅的时候就开始打印数据,需要注意的是,just()方法最多可传10个参数,它们会按照传入的参数的顺序来发射它们

private void testRxMethod_just() {
        Observable observable = Observable.just("1", "2", "3","4", "5","6","7","8","9","10");
        Subscriber subscriber = new Subscriber()
        {
            @Override
            public void onCompleted() {
                Log.i("rxjava", "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.i("rxjava", "error");
            }
            @Override
            public void onNext(String o) {
                Log.i("rxjava", o);
            }};
        observable.subscribe(subscriber);
   }

1.3.from—该方法参数是一个数组,然后from会将其拆分为一个个对象,发射出去

private void testRxMethod_from() {
        List items = new ArrayList<>();
        items.add("1");
        items.add("2");
        items.add("3");
        Observable observable = Observable.from(items);
        Subscriber subscriber = new Subscriber()
        {
            @Override
            public void onCompleted() {
                Log.i("rxjava", "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.i("rxjava", "error");
            }
            @Override
            public void onNext(String o) {
                Log.i("rxjava", o);
            }};
        observable.subscribe(subscriber);
    }
11-17 14:44:13.043 30921-30921/pa.test.com.testapp I/rxjava: 1
11-17 14:44:13.043 30921-30921/pa.test.com.testapp I/rxjava: 2
11-17 14:44:13.043 30921-30921/pa.test.com.testapp I/rxjava: 3
11-17 14:44:13.043 30921-30921/pa.test.com.testapp I/rxjava: onCompleted

1.4.interval-定时器,该方法会每隔一段时间发射消息,interval()函数的两个参数:一个指定两次发射的时间间隔,另一个是用到的时间单位。

private void testRxMethod_interval() {
        Observable.interval(2, TimeUnit.SECONDS)
                .subscribe(new Observer() {

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

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

                    @Override
                    public void onNext(Long number) {
                        Log.i("rxjava", "onNext"+number);
                    }
                });
    }

1.5.timer—可达到延时器效果之用,订阅后,Observable发射出一个0,就结束了,调用 onCompleted().

private void testRxMethod_timer() {
         Observable.timer(3,TimeUnit.SECONDS)
                 .subscribe(new Observer() {

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

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

                     @Override
                     public void onNext(Long number) {
                         Log.i("rxjava", "onNext"+number);
                     }
                 });
     }

2.Observable变换以及过滤

2.1.map—是对对象的一种直接变换函数,它会接受一个Fun函数当作入参,然后将它应用到每一个由Observable发射的值上,它将输入的数据处理后,返回一种新形式的数据,可以是任一类型。应用场景可以是:将图片路径(String)处理后返回Bitmap图片,或者计算原始数据,处理后成为需要的数据。

private void testRxMethod_map() {
        Observable.just(6)
                .map(new Func1<Integer, String>() {
                    @Override
                    public String call(Integer integer) {
                        return integer/3+"";
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("lqm","call:"+s);
                    }
                });
    }

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

private void testRxMethod_flatMap() {
        Observable.just("girl;boy;man")
                .flatMap(new Func1>() {
                    @Override
                    public Observable call(String s) {
                        return Observable.from(s.split(";"));
                    }
                })
                .subscribe(new Action1() {
                    @Override
                    public void call(String s) {
                        Log.d("lqm", "onNext:" + s);
                    }
                }, new Action1() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.d("lqm", "onerror");
                    }
                }, new Action0() {
                    @Override
                    public void call() {
                        Log.d("lqm", "onComplete");
                    }
                });
    }
11-17 15:41:04.743 18653-18653/pa.test.com.testapp D/lqm: onNext:girl
11-17 15:41:04.743 18653-18653/pa.test.com.testapp D/lqm: onNext:boy
11-17 15:41:04.743 18653-18653/pa.test.com.testapp D/lqm: onNext:man
11-17 15:41:04.743 18653-18653/pa.test.com.testapp D/lqm: onComplete

要对比下flatMap跟map,flatMap传入的参数是Observable,返回的也是 Observable,虽然两者都是传入一个对象,再转化成一个新对象,但是这一点还是很有区别的,关于flatMap的原理,这边引用下扔物线的一段话来解释:flatMap() 的原理是这样的:1. 使用传入的事件对象创建一个 Observable 对象;2. 并不发送这个 Observable, 而是将它激活,于是它开始发送事件;3. 每一个创建出来的 Observable 发送的事件,都被汇入同一个 Observable ,而这个 Observable 负责将这些事件统一交给 Subscriber 的回调方法。

2.3filter—过滤方法,使用这个方法来过滤掉一些我们不需要的数据,返回false,说明该对象不符合要求,会被过滤; 返回true,说明该对象可以正常往下走,符合标准。

private void testRxMethod_filter() {
        String[] strArr = {"a123","b123","c123","d123"};
        Observable.from(strArr)
                .filter(new Func1() {
                    @Override
                    public Boolean call(String s) {
                        return s.contains("a") || s.contains("b") || s.contains("c");
                    }
                })
                .subscribe(new Action1() {
                    @Override
                    public void call(String s) {
                        Log.d("lqm","call:"+s);
                    }
                });
    }
11-17 20:39:54.761 32378-32378/pa.test.com.testapp D/lqm: call:a123
11-17 20:39:54.761 32378-32378/pa.test.com.testapp D/lqm: call:b123
11-17 20:39:54.761 32378-32378/pa.test.com.testapp D/lqm: call:c123

2.4 distinct—在一个序列中去掉重复数据

private void testRxMethod_distinct() {
        Observable.just("Jack", "Honey","Lucy","Lucy","Jane")
                .distinct().subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                Log.i("lqm","onCompleted");
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {
                Log.i("lqm","onNext" + s);
            }
        });
    }
11-17 20:47:00.141 19536-19536/pa.test.com.testapp I/lqm: onNextJack
11-17 20:47:00.141 19536-19536/pa.test.com.testapp I/lqm: onNextHoney
11-17 20:47:00.141 19536-19536/pa.test.com.testapp I/lqm: onNextLucy
11-17 20:47:00.141 19536-19536/pa.test.com.testapp I/lqm: onNextJane
11-17 20:47:00.141 19536-19536/pa.test.com.testapp I/lqm: onCompleted

这边需要注意的是,distinct只能区别基本类型的重复以及是否同一对象,若是不同对象内容相同,是不能去重的

 private void testRxMethod_distinct() {
        RxBeanInfo info1 = new RxBeanInfo();
        info1.setName("jack");
        RxBeanInfo info2 = new RxBeanInfo();
        info2.setName("jack");
        RxBeanInfo info3 = new RxBeanInfo();
        info3.setName("jack");

        Observable.just(info1,info2,info3)
                .distinct().subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                Log.i("lqm","onCompleted");
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(RxBeanInfo s) {
                Log.i("lqm","onNext" + s.getName());
            }
        });
    }
11-17 20:50:01.101 25465-25465/pa.test.com.testapp I/lqm: onNextjack
11-17 20:50:01.101 25465-25465/pa.test.com.testapp I/lqm: onNextjack
11-17 20:50:01.101 25465-25465/pa.test.com.testapp I/lqm: onNextjack
11-17 20:50:01.101 25465-25465/pa.test.com.testapp I/lqm: onCompleted

这些API是比较常用了,目前就讲到这些,如果有兴趣的,可以去给Android开发者的RxJava 详解去细看。

二.线程转换要点

这边主要介绍的是RxJava 的 Schedulers(调度器) 功能

对于任何 Observable 你可以定义在两个不同的线程。
1. 使用 Observable.observeOn() 可以定义在一个线程上,可以用来监听和检查从 Observable 最新发出的 items (Subscriber 的 onNext,onCompleted 和 onError 方法会执行在 observeOn 所指定的线程上)。
2. 使用 Observable.subscribeOn() 来定义一个线程,subscribeOn() 指定 subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。

RxJava 默认情况下是单线程的,你会需要利用 observeOn() 和 subscribeOn() 方法为你的应用带来多线程操作。RxJava 附带了几个现成的 Schedulers 给 Observables 使用,如:Schedulers.io() (用于 I/O 操作),Schedulers.computation()(计算工作),和 Schedulers.newThread()(为任务创建的新线程),另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。

了解到这些,我们来看看实际Rxjava是在线程间是如何运行的,这边会分case 来详解
1.只配置了 observeOn,但是在不同的位置,会有什么样的影响呢?

    private void observableEvent() {
        Log.d("lqm","mainthread :"+android.os.Process.myTid());
        Observable.just(1)
                .map(new Func1() {
                    @Override
                    public String call(Integer integer) {
                        Log.d("lqm","map:"+android.os.Process.myTid());
                        return integer+"a";
                    }
                })
                .filter(new Func1() {
                    @Override
                    public Boolean call(String s) {
                        Log.d("lqm","filter:"+android.os.Process.myTid());
                        return s.contains("1");
                    }
                })
                .observeOn(Schedulers.io())
                .subscribe(new Action1() {
                    @Override
                    public void call(String s) {
                        Log.d("lqm","call:"+android.os.Process.myTid());
                    }
                });
    }
11-17 21:08:58.551 7624-7624/pa.test.com.testapp D/lqm: mainthread :7624
11-17 21:08:58.591 7624-7624/pa.test.com.testapp D/lqm: map:7624
11-17 21:08:58.591 7624-7624/pa.test.com.testapp D/lqm: filter:7624
11-17 21:08:58.591 7624-8857/pa.test.com.testapp D/lqm: call:8857

从上面运行结果可以看出,主线程id为7624,map()和filter()运行在主线程,由于调用subscribe()时调用了observeOn(Schedulers.io()),所以call()方法运行在io线程上。

那如果我们将observeOn()提前呢,会不会对线程造成影响呢?

private void observableEvent() {
        Log.d("lqm","mainthread :"+android.os.Process.myTid());
        Observable.just(1)
                .observeOn(Schedulers.io())
                .map(new Func1() {
                    @Override
                    public String call(Integer integer) {                                  Log.d("lqm","map:"+android.os.Process.myTid());
                        return integer+"a";
                    }
                })
                .filter(new Func1() {
                    @Override
                    public Boolean call(String s) {                    Log.d("lqm","filter:"+android.os.Process.myTid());
                        return s.contains("1");
                    }
                })
                .subscribe(new Action1() {
                    @Override
                    public void call(String s) {                      Log.d("lqm","onNext:"+android.os.Process.myTid());
                    }
                });
    }
11-18 10:02:35.691 21563-21563/pa.test.com.testapp D/lqm: mainthread :21563
11-18 10:02:35.711 21563-22093/pa.test.com.testapp D/lqm: map:22093
11-18 10:02:35.711 21563-22093/pa.test.com.testapp D/lqm: filter:22093
11-18 10:02:35.711 21563-22093/pa.test.com.testapp D/lqm: onNext:22093

看到了没有,现在map(),filter()和onNext()都运行在IO线程上了
所以目前来看,observeOn()对除了Subscriber操作产生影响,还对map,filter等产生影响,但是只会对ObserveOn()操作后的动作产生影响

接下来继续测试。

你可能感兴趣的:(rxjava,Android,Rx,RxJava)