android rxjava框架 1.0 操作符介绍

rxjava目前其实已经更新到2.0版本了,但我还是想从1.0开始学习下如何使用,其实你知道了1.0版本如何使用,2.0版本也是知道了,不可能改的面目全非,rxjava是一个异步框架,比如我们android中请求一个网络然后通知ui更新,如果使用最原始的方法就时new一个Thread然后结合Handler去更新UI,但是如果你使用了rxjava就不比这么麻烦了,学习一个框架如何使用就是在github上看它的文档然后结合它给的demo,自己实现一遍就知道的差不多了,我说的是使用,而不是理解里面的源码

地址在这里:https://github.com/ReactiveX/RxAndroid/tree/1.x


rxjava框架的引入在github上也有讲:在build.grade下引入这二个包

compile 'io.reactivex:rxandroid:1.2.1'
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.
compile 'io.reactivex:rxjava:1.1.6'
就这么简单的就引入了rxjava1.0


rxjava是响应式编程,所谓响应式,就是存在二部分,一部分负责发送事件或者消息,另一部分负责接收事件或者消息

rxjava其实入门使用并不像其他框架使用起来那么简单,主要是和我门Java面向对象的思维方式不一样导致的,今天通过这篇博客,希望看到的人都能很好的入门。

rxjava核心原理是使用了扩展的观察者模式,就一般的观察者模式我们都知道,比如马云爸爸喜欢看今日头条,但是他喜欢怀旧,而不是用手机看,喜欢看纸装的那种,那马云爸爸那么忙,不可能每天去报摊上去买,而且也不可能,毕竟现在比一些娱乐明星还红,所以就按一年的去订,只要有新的报纸出来,就会有报童主动送到马云爸爸家里,类似如图:





从上面的图中我们可以根据描述以及图提取几个关键的概念:


上面的订阅操作就把观察者和被观察者关联了起来.

从上面的举例中发现观察者要具备三个因素

第一:被观察者

第二:观察者

第三:订阅(让观察者和被观察者产生关联的动作)

把上面的三条翻译成Java开发认识的观察者是observer,被观察者是Observable,订阅就是subscribe.那我们就把这三个条件同样用于rxjava学习当中.

那现在根据上面三个条件开始学习rxjava使用

第一步:创建被观察者

//今日头条报社 被观察者(Observable)
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {

    }
});
第二步:创建观察者
//家庭  观察者(ObserverObserver<String> observer = new Observer<String>(){
    @Override
    public void onCompleted() {

    }
    @Override
    public void onError(Throwable e) {

    }
    @Override
    public void onNext(String s) {

    }
};
有了上面二步,但是这并没有让观察者和被观察者产生关联,这个时候他们二个并没有如何联系,所以还需要第三步

第三步:关联(让观察者和被观察者产生关联)也就是订阅了

observable.subscribe(observer);
这个时候如果被观察者也就是Observale发出了什么消息,观察者Observer就会收到什么消息了.那被观察者也就是Observale怎么发送消息呢?这样的:
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        //onNext就相当于subscriber要发送报纸的
        subscriber.onNext("hello world rxjava");
    }
});
而切切我们观察者Observer中刚好也有个OnNext()方法,这就是观察者接受到被观察者发送的消息了,也就是说报社发送了报纸,马云爸爸接受到了报纸,这是说这个报纸是一个string类型而已,当然这个由你自定义定义了.
Observer<String> observer = new Observer<String>(){
    @Override
    public void onCompleted() {

    }
    @Override
    public void onError(Throwable e) {

    }
    @Override
    public void onNext(String s) {
        //接受到被观察者发送的消息
        Log.e(TAG,"接收到被观察者发送的消息是"+s);
    }
};
下面onNext()方法中s就是被观察者发送出来的消息了,所以呢?onNext()方法对Observale是发送消息的行为,而对Observer来说是接受消息的行为

它的原理是这样的:


当然我们可以在Observale下可发出多个消息这是可以的.

我们在Observer(观察者)的回调当中是有三个方法的,分别是onCompleted(),onNext(),onError(),如果你打log去看的话,其实当接收到消息后其实并没有回调onCompleted(),是的,并不会,那要追踪到Observale发送消息的了,再次看下这个代码:

Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        //onNext就相当于subscriber要发送报纸的
        subscriber.onNext("hello world rxjava");
    }
});
看下Subscriber类中都有啥方法:
public abstract class Subscriber<T> implements Observer<T>, Subscription {
它是一个抽象的类,实现了二个接口,看下Observer这个接口有啥方法:


也就是说Subscriber类中也有这三个方法,再想到我们发送消息用的是onNext(),这个时候如果在onNext()之后调用onCompleted()方法的话Observer的onCompleted()方法就会执行,比如你有个网络请求,当你拿到服务器返回的数据后,要做其他的事情的话,就可以在OnCompleted()回调中去做其他的业务.当你执行了onCompleted()方法以后你再调用onNext()方法,Observer是接收不到消息的,相当于取消了订阅

Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        //onNext就相当于subscriber要发送报纸的
        subscriber.onNext("hello world rxjava");
        subscriber.onCompleted();
        subscriber.onNext("再次发送hello world rxjava");
    }
});
第二个消息是受不到的,自己可以打log去看结果,来验证我的说法,

结论:只要调用了onCompleted()后面的事件就收不到

还有一个方法就是OnError()了,这个在你发送异常的时候进行回调的.

Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        //onNext就相当于subscriber要发送报纸的
        subscriber.onNext("hello world rxjava");
        subscriber.onError(new NullPointerException());
        subscriber.onNext("再次发送hello world rxjava");
        subscriber.onCompleted();
    }
});
你会发现一旦调用了onError()方法,就不会再发送下面的消息了

结论:一旦调用了onError()方法,就不会再发送下面的消息了


特殊的被观察者(Single)

Single它作为被观察者只能发送一次,订阅就终止了,不像Observale有onCompleted(),onNext(),onError()这方法,它发送是通过onSuccess()发送成功,或者调用onError()发送失败,

public void signle(View view){
    Single single = Single.create(new Single.OnSubscribe<String>(){
        @Override
        public void call(SingleSubscriber<? super String> singleSubscriber) {
            singleSubscriber.onSuccess("发送消息11111111111");
            singleSubscriber.onSuccess("发送消息2222222222222222");
        }
    });
    Observer observer = new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"接收到的消息s="+s);
        }
    };
    single.subscribe(observer);
}
log:


从log我们也发现Single只能发送一次消息或者事件,而且观察者接受到了以后会调用onCompleted()方法,其实我们是发送了二次消息的,如果有特殊的需求是可以用这个的,有点类似我们的单例

总结:Single只能发送一次消息也就是只能调用一次OnSuccess()或者onError()


特殊的观察者

我们通常使用的观察者是Observer,其实还有一种,进入Observale类找到subscribe()方法,他有几个重载方法:

public final Subscription subscribe(Subscriber<? super T> subscriber) {
    // validate and proceed
    if (subscriber == null) {
        throw new IllegalArgumentException("observer can not be null");
    }
传递的是Subscribe这个对象,
public abstract class Subscriber<T> implements Observer<T>, Subscription {
发现他其实是Observer的子类,所以也是可以的,写个demo玩玩
//另一种观察者
public void subscriber(View view){
    Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("今天周一好蛋疼");
            subscriber.onCompleted();
        }
    });
    Subscriber subscriber = new Subscriber<String>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"接收到的消息是::::"+s);
        }
    };
    observable.subscribe(subscriber);
}
log:


结果是和Observer一样的,他们的区别在于Subscriber 提供了取消订阅和判断是否已经订阅了,如果有一种需求就是如果消息接受到了话要取消订阅的话,就使用这个.

其实我们开发中可能就只要接受消息的onNext()方法即可,希望不要onCompleted()和onError()方法,不用放在那里,挺不好看的,这个也是可以做到的,我们看下Observale给我们提供的方法:

public final Subscription subscribe(final Action1<? super T> onNext)
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError) {
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onCompleted) {
有这三个重载的方法可以给我们使用,现在玩下:
public void onNext(View view){
    Observable observable = Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("今天周一好蛋疼");
            subscriber.onCompleted();
        }
    });
    Action1 onNext = new Action1<String>(){
        @Override
        public void call(String s) {
            Log.e(TAG,"接收到的消息是:::"+s);
        }
    };
    Action1 onError = new Action1<Throwable>(){
        @Override
        public void call(Throwable throwable) {
            Log.e(TAG,"接收到异常:::"+throwable.toString());
        }
    };
    Action0 onCompleted = new Action0(){
        @Override
        public void call() {
            Log.e(TAG,"消息发送完毕:::");
        }
    };
    //只接受onNext()
    observable.subscribe(onNext);
}
log:


至于你还想接受onCompleted事件的话,上面已经写好了,传递进去就行了.上面用到了如果没有参数就是Action0,一个参数是Action1,他们就是Action的实现类,看下Action这个接口有多少实现类:


都到9了,因为没有10,呵呵,还有个ActionN就是要你自己自定义了,一般很难用到,在这也是说一下而已.

public interface ActionN extends Action {
    void call(Object... args);
}
他接受的是一个可变参数。和Action对应的还有个Func0到Func9,写个demo玩下:
Func0 f0 = new Func0<String>(){
    @Override
    public String call() {
        return null;
    }
};
Func1 f1 = new Func1<String,Integer>(){
    @Override
    public Integer call(String s) {
        return null;
    }
};

Func也有从0到9,他的call()方法是有返回值的,返回值是泛型的最后一个.


雌雄同体的Subject

为什么说Subject是雌雄同体呢?看下它的类结构就知道了,


它即继承了Observable,又实现了Observer接口,所以Subject即是观察者又是被观察者,这是冷战时期的双面间谍,但是一般都是使用它作为被观察者,也就是说当做Observable用,他是一个抽象类,来看看给我们提供了什么子类使用,


有8个子类啊,先看第一个子类,介绍下有啥用


AsyncSubject

如果你点击进去看了他的注释,代码都给你写好了,直接copy出来运行下就行,文档还是很不错的,

public void asyncsubject(View view){
    AsyncSubject<String> subject = AsyncSubject.create();
    subject.onNext("one");
    subject.onNext("two");
    subject.onNext("three");
    subject.onCompleted();
    Action1<String> action1 = new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,"接受到的消息是:::"+s);
        }
    };
    subject.subscribe(action1);
}
log:


你会看到他只接受了额一个消息,但是我们发送的是三个消息对吧,这就是AsyncSubject这个对象的特点,

AsyncSubject特点:只会接受一个消息,就是发送的最后一个消息,从类的类名就可以看的出来,他是异步的,也就是说不等调用subscribe()方法,创建后就可以发送消息了,如果你不调用onCompleted()发送,是发送不出任何一个消息的,


BehaviorSubject

学习这个类也是从他的类注释已经给我们写好了demo,copy过来

public void behaviorsubject(View view){
    BehaviorSubject<String> subject = BehaviorSubject.create("default");
    Action1<String> action1 = new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,"接受到的消息是:::"+s);
        }
    };
    subject.onNext("zero");
    subject.onNext("one");
    subject.subscribe(action1);
    subject.onNext("two");
    subject.onNext("three");
}
log:


zero,one是订阅前发送的, two,thred是订阅后发送的,但是他并没有打印zero。所以他的特点就出来了,会发送订阅前最后一个和订阅后所有的事件;现在我订阅前一个事件都不发送,再试试

public void behaviorsubject(View view){
    BehaviorSubject<String> subject = BehaviorSubject.create("default");
    Action1<String> action1 = new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,"接受到的消息是:::"+s);
        }
    };
    subject.subscribe(action1);
    subject.onNext("two");
    subject.onNext("three");
}
log:


所以啊,如果订阅前不发送任何事件的话,就会发送默认一个事件了

结论:BehaviorSubject会发送订阅前最后一个和订阅后所有的事件,如果订阅前没有任何事件发送的话,就会发送默认事件了


PublishSubject

同样的学习方法,把他的类注释上的代码copy过来

public void publishsubject(View view){
    PublishSubject<String> subject = PublishSubject.create();
    Action1<String> action1 = new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,"接受到的消息是:::"+s);
        }
    };
    subject.onNext("one");
    subject.onNext("two");
    subject.subscribe(action1);
    subject.onNext("three");
    subject.onNext("four");
    subject.onCompleted();
}
log:


你会发现明明我是发送了四个事件,但是只接收到了最后二个,最后二个是在订阅后发送的,是的,他也是在创建后就可以发送事件,但是观察者只接受到他订阅后的事件

结论:PublishSubject创建后就可以发送事件,但是观察者只能接收到他订阅后发送的事件

ReplaySubject

同样的学习方法,从类注释上copy他的例子

public void replaysubject(View view){
    ReplaySubject<String> subject = ReplaySubject.create();
    Action1<String> action1 = new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,"接受到的消息是:::"+s);
        }
    };
    subject.onNext("one");
    subject.onNext("two");
    subject.subscribe(action1);
    subject.onNext("three");
    subject.onCompleted();
}
log:


从这log中我们很好的知道,不管什么时候发送事件,观察者都能接收到

结论:ReplaySubject不管在订阅后还是前发送事件,观察者都能接受到

接下来就开始学习各种操作符了


publish操作符

是将一个普通的被观察者变成一个可连接的被观察者

public void publish(View view){
    Observable<String> observable = Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("hello world rxjava");
            subscriber.onCompleted();
        }
    });
    //通过publish操作符变成一个可连接的observable
    ConnectableObservable connectableObservable = observable.publish();
    Observer<String> observer = new Observer<String>(){
        @Override
        public void onCompleted() {
        }
        @Override
        public void onError(Throwable e) {
        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"接收到被观察者发送的消息是"+s);
        }
    };
    connectableObservable.subscribe(observer);
}
你会发现啥都不会打印,也就是说Observable中的call()方法并没有调用,想要调用的话,还要添加如下代码:
connectableObservable.connect();
是在subscribe()方法之后调用才有效.这个时候再运行起来,log


publish操作符的作用就是帮助我们想要发送的事件统一发送,在调用connect()之后订阅观察者是接受不到消息的

其实Observable和ConnectableObservable是可以互相转换的,如图



replay操作符

上面的publish操作是一个普通的Observable变成一个可连接的ConnectableObservable,但是有个缺点就是在调用connect()方法之后在订阅的话,是接收不到消息的,如果想要接收到被观察者发送的消息的话,就要使用replay操作符了

public void replay(View view){
    Observable<String> observable = Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("hello world rxjava");
            subscriber.onCompleted();
        }
    });
    //通过replay操作符变成一个可连接的observable
    ConnectableObservable connectableObservable = observable.replay();
    Observer<String> observer = new Observer<String>(){
        @Override
        public void onCompleted() {
        }
        @Override
        public void onError(Throwable e) {
        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"消息111"+s);
        }
    };
    connectableObservable.subscribe(observer);
    connectableObservable.connect();
    connectableObservable.subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"消息222"+s);
        }
    });
}
log:


replay操作符是让一个普通的Observable变成一个可连接的ConnectableObservable在connect()之后还可以让观察者接受到发送的消息


defer操作符

Observable除了使用create()方法创建Observable还有其他的方法,比如defer,先还是老样子,写demo

public void defer(View view){
    Observable observable = Observable.defer(new Func0<Observable<String>>() {
        @Override
        public Observable<String> call() {
            return null;
        }
    });
   Observer observer = new Observer<String>() {
       @Override
       public void onCompleted() {

       }
       @Override
       public void onError(Throwable e) {

       }
       @Override
       public void onNext(String s) {

       }
   };
    observable.subscribe(observer);
}
用defer创建的Observable,你会发现有二个地方和之前使用create()创建的Observable不同之处,第一个不同在于call()方法有返回值,第二call没有参数,这样怎么发送消息呢?而且返回的值是一个Observable对象,那么好我就创建一个Observable,
Observable observable = Observable.defer(new Func0<Observable<String>>() {
    @Override
    public Observable<String> call() {
        Observable observable = Observable.create(new OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                //发送数据
                subscriber.onNext("发送消息的数据");
            }
        });
        return observable;
    }
});
这样观察者才能接收到发送的数据,你订阅多个观察者也能接收到发送的对象,再写一个例子,结合log来分析:
public void defer(View view){
    Observable observable = Observable.defer(new Func0<Observable<String>>() {
        @Override
        public Observable<String> call() {
            Observable observable = Observable.create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    //发送数据
                    subscriber.onNext("发送消息的数据");
                }
            });
            Log.e(TAG,"observable:::"+observable);
            return observable;
        }
    });
   Observer observer = new Observer<String>() {
       @Override
       public void onCompleted() {

       }
       @Override
       public void onError(Throwable e) {

       }
       @Override
       public void onNext(String s) {
            Log.e(TAG,"接受到的消息是:::"+s);
       }
   };
    Observer observer1 = new Observer<String>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"1111接受到的消息是:::"+s);
        }
    };
    observable.subscribe(observer);
    observable.subscribe(observer1);
}
log:


从上面的创建Observable对象值来看,他每次创建的都是不同的对象,而且是在订阅观察者之后才会去创建对象,并发送消息

结论:Observable创建的Observable对象发现并没什么用,他是在订阅之后也就是调用了subscribe()方法之后在其内部创建了Observable对象和观察者进行关联起来,每关联一个观察者对象,被观察者内部都会创建一个Observable对象


Jsut操作符

直接来代码,什么都不必说

public void just(View view){
    Observable
            .just("想让自己内心丰富起来么","那就多读书吧")
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                    Log.e(TAG,"onCompleted");
                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"接收到的消息::::="+s);
                }
            });
}
log:


我们发现观察者接收到了二个消息,而且onCompleted()方法还被调用了

结论:just操作符代替create()方法创建Observable发送多个消息,内部还自动调用了onCompleted(),使用这个比create()能节省代码,而且看起来特别舒服


from操作符

from操作符是操作队列的,说白了就是操作集合什么的,也是和create()类似,可以创建一个Observable对象

public void from(View view){
    List<String> lists = new ArrayList<>();
    for(int i=0;i<5;i++){
        lists.add("美女--"+i);
    }
    Observable.from(lists)
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                    Log.e(TAG,"onCompleted=");
                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"s="+s);
                }
            });
}
log:


发现当观察者接收到事件后,也会调用onCompleted(),from()方法参数还是会接受一个数组,

结论:from操作符可以操作队列中的数据


interval操作符

interval操作符就是定时去执行某个任务,和Java中的Timer类似,

public void interval(View view){
    Observable
            .interval(1000, TimeUnit.MILLISECONDS)
            .subscribe(new Observer<Long>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Long l) {
            Log.e(TAG,"上课倒计时还有::"+l+"");
        }
    });
}
log:


这个interval操作符理解起来很简单了,就是定时去发送事件,


timer操作符

timer操作符和interval很像,

public void timer(View view){
    Observable.timer(5000,TimeUnit.MILLISECONDS).subscribe(new Observer<Long>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Long aLong) {
            Log.e(TAG,"要上课了::"+aLong);
        }
    });
}
timer操作符就是延迟多久发送消息


range操作符

range操作符就是让某个操作执行多次

public void range(View view){
    Observable
         .range(1,6)
         .subscribe(new Observer<Integer>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted:::");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Integer integer) {
            Log.e(TAG,"integer:::"+integer);
        }
    });
}
log:


就没啥好说的了,唯一说的是onCompleted()会被调用


repeat操作符

repeat操作符和range操作符很像,都是重复执行某个操作

public void repeat(View view){
    Observable
    .just("重要的事说三遍")
     .repeat(3)
      .subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted:::");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,s);
        }
    });
}
log:


如果repeat()不传递重复的次数的话,他会一直执行某个操作,累不死他


delay操作符

delay就是延迟多久去执行某个任务

public void delay(View view){
    Observable
            .just("2秒你去完成登录功能","3秒去完成注册功能")
            .delay(5,TimeUnit.SECONDS)
            .subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted:::");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"今天要干的活---"+s);
        }
    });
}


distinct操作符

distinct操作符作用就是过滤重复的数据,比如现在有个需求就是你公司可能去冬游,要把去参加的人名单确认下,这个时候你要核对人数了,可能会有名字重复的,但是是不同的人,那么只有根据身份证来过滤了

public void distinct(View view){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘英","341839855558925",30));
    Observable
            .from(persons)
            .distinct(new Func1<Person, String>() {
                @Override
                public String call(Person person) {
                    return person.getId_card();
                }
            })
            .subscribe(new Observer<Person>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Person person) {
            Log.e(TAG,"去参数冬游的有:"+person);
        }
    });
}
log:


从log就可以看的出distinct操作符可以根据某个条件去过滤结果


filter操作符

filter也是过滤指定某个条件下的数据

public void filter(View view){
    Observable
         .range(-2,5)
         .filter(new Func1<Integer, Boolean>() {
        @Override
        public Boolean call(Integer integer) {
            return integer>0;
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Integer integer) {
            Log.e(TAG,integer%2+"");
        }
    });
}

你会看到当我拿到结果对他进行%2操作,而且要求这数必须是大于0的,那么这个时候你就要过滤掉-2,-1,0这三个数字了,这是这个意思


first操作符

first操作符就是获取队列中的第一个数据

public void first(View view){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘茹英","341839855558925",35));
    Observable.from(persons).first().subscribe(new Observer<Person>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Person person) {
            Log.e(TAG,person.toString());
        }
    });
}
log:



last操作符

和first操作符相反,获取的是队列中最后一个元素

public void last(View view){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘茹英","341839855558925",35));
    Observable
            .from(persons)
            .last().
            subscribe(new Observer<Person>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Person person) {
            Log.e(TAG,person.toString());
        }
    });
}
log:


既然提供了获取队列中的开头和结尾,那么中间的怎么获取呢?就要讲到下面的操作符了


elementAt操作符

就是获取队列中根据传递的角标值或者他对应的元素

public void elementAt(View view){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘茹英","341839855558925",35));
    Observable
            .from(persons)
            .elementAt(1).
            subscribe(new Observer<Person>() {
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(Person person) {
                    Log.e(TAG,person.toString());
                }
            });
}
log:


感觉好无聊啊,这个操作符,为啥有了这个还要提供first和last呢?


take操作符

take操作符是获取队列中某几个元素

public void task(View view){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘茹英","341839855558925",35));
    Observable
            .from(persons)
            .take(2).
            subscribe(new Observer<Person>() {
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(Person person) {
                    Log.e(TAG,person.toString());
                }
            });
}
这是获取集合中前二个Person对象

log:


take还有重载的方法take(long time, TimeUnit unit),就是指定单位时间内的发送的消息,这个要配合invetal操作符好演示

Observable.interval(1000,TimeUnit.MILLISECONDS).take(5000,TimeUnit.MILLISECONDS).subscribe(new Observer<Long>() {
    @Override
    public void onCompleted() {
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(Long aLong) {
        Log.e(TAG,"aLong="+aLong);
    }
});
log:


tastLast操作符

获取某队列中后几个元素

public void takeLast(View view){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘茹英","341839855558925",35));
    Observable
            .from(persons)
            .takeLast(2).
            subscribe(new Observer<Person>() {
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(Person person) {
                    Log.e(TAG,person.toString());
                }
            });
}
log:


sample操作符

sample是对发送数据进行一定频率的采样发送

public void sample(View view){
    Observable
            .interval(1000,TimeUnit.MILLISECONDS)
            .sample(2000,TimeUnit.MILLISECONDS)
            .subscribe(new Observer<Long>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Long aLong) {
            Log.e(TAG,"aLong="+aLong);
        }
    });
}
log:


本来是每秒发送一个数据,现在是进行采样,每2秒发送一次数据,那么观察者接收到的就是每2秒发送过来的数据了

ignoreElements操作符

ignoreElements操作符就是忽略掉你发送的数据,我只要知道什么时候发送完毕了就行,不要进行消息的接受

public void ignoreElements(View view){
    Observable
              .just("发送第一个消息","发送第二个消息","发送第三个消息")
            .ignoreElements()
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                    Log.e(TAG,"onCompleted");
                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,s);
                }
            });
}
log:


你会发现onNext()并没有接受到消息,只打印了onCompleted(),因为被忽略了啊

all操作符

all操作符是用于判断队列中的元素是否满足某个条件,只要有一个不满足就返回false,否则则true,

public void all(View view){
    Observable
        .from(getPersons())
        .all(new Func1<Person, Boolean>() {
        @Override
        public Boolean call(Person person) {
            return person.getAge()>30;
        }
       })
        .subscribe(new Observer<Boolean>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Boolean aBoolean) {
            Log.e(TAG,"aBoolean="+aBoolean);
        }
    });
}
public List<Person> getPersons(){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘茹英","341839855558925",35));
    return persons;
}

amb操作符

amb操作符就是让二个被观察者合并成一个新的被观察者,

public void amb(View view){
    Observable<String> aObservable = Observable.just("小明先1秒后","跑到了终点");
    Observable<String> bObservable = Observable.just("小王先2秒后","跑到了终点");
    Observable
            .amb(aObservable,bObservable)
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    Log.e(TAG,"s="+s);
                }
            });
}
log:


结论:amb操作符会先发送那个发送数据被观察者中的数据,后面的被观察者发送的数据就会被忽略

contains操作符

contains判断被观察者发送的数据是否还有某个值

public void  contains(View view){
    Observable
            .just(0,1,2)
            .contains(0)
            .subscribe(new Action1<Boolean>() {
                @Override
                public void call(Boolean aBoolean) {
                    Log.e(TAG,"aBoolean="+aBoolean);
                }
            });
}
log:


从结果我们知道发送的数据是包含0的

defaultIfEmpty操作符

比如我们注册或者登陆的时候,EditText中会有默认提示请输入用户账号之类的文字,defaultIfEmpty操作符就是这个功能,当被观察者没有发送数时,如果使用了defaultIfEmpty操作符就会发送这个默认的数据,观察者就会接受这个数据,前提是必须要调用subscriber.onCompleted();否则默认值这个被观察者是不会发送消息的。

public void defaultIfEmpty(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onCompleted();
                }
            })
            .defaultIfEmpty("你输入用户账号")
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    Log.e(TAG,"s="+s);
                }
            });
}
log:


sequenceEqual操作符

sequenceEqual操作符就是判断二个被观察者发送的数据是否相等,如果发送的数据相等而且必须是顺序也一样才返回true,如果发送的数据一样但是顺序不一样还是会返回false的

public void sequenceEqual(View view){
    Observable pwd = Observable.just(1,2,3,4,5,6);
    Observable confimwd = Observable.just(1,2,3,4,5,6);
    Observable
            .sequenceEqual(pwd,confimwd)
            .subscribe(new Action1<Boolean>() {
        @Override
        public void call(Boolean aBoolean) {

        }
    });
}

skip操作符

skip从单词就知道其意思了,就是跳过的意思

如果有个需求,需要把发送的数据过滤下,前面的某些数据不要发送,发送后面几个数据就行了,

public void  skip(View view){
    Observable
           .range(1,10)
            .skip(5)
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    Log.e(TAG,"integer="+integer);
                }
            });
}
log:


skipLast操作符

就是跳过发送数据的后几位

public void  skipLast(View view){
    Observable
            .range(1,10)
            .skipLast(5)
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    Log.e(TAG,"integer="+integer);
                }
            });
}
log:


skipWhile操作符

skipwhile是跳过发送的每一个数据,直到条件为false时才让观察者接受被观察者发送过来的数据

public void  skipWhile(View view){
    Observable
            .just(1,2,3,4,5)
            .skipWhile(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer value) {
                    return value<3;
                }
            })
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    Log.e(TAG,"integer="+integer);
                }
            });
}
log:


记住为false才发送数据,切记

takeWhile操作符

takeWhile和skipWhile是相反的,takeWhile是接受每一个数据,直到结果返回为true的时候才发送每一个数据,不满足条件的就不会发送数据

public void takeWhile(View view){
    Observable
            .just(1,2,3,4,5)
            .takeWhile(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer value) {
                    return value<3;
                }
            })
            .subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer integer) {
            Log.e(TAG,"integer="+integer);
        }
    });
}
log:


average操作符

其实并没有average操作符,这个是求平均值的,但是他有四个averageInteger,averageDouble,averageFloat,averageLong,我只是把这其中总结了下而已,不可能这四个都要写,在这要注意的是,在rxjava中关于值运算的操作符要引入另外一个开发包在你的Module的build下

compile 'io.reactivex:rxjava-math:1.0.0'

public void average(View view){
    Observable observable  = Observable.just(1,2,3,4,5,6,7,8,9,10);
    MathObservable.averageInteger(observable).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer aDouble) {
            Log.e(TAG,"平均值为"+aDouble);
        }
    });
}
log:


max操作符

max求队列中的最大值

public void max(View view){
    Observable observable  = Observable.just(1,2,3,4,5,6,7,8,9,10);
    MathObservable.max(observable).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer value) {
            Log.e(TAG,"最大值为"+value);
        }
    });
}
log:


min操作符

min求队列中的最小值

public void min(View view){
    Observable observable  = Observable.just(1,2,3,4,5,6,7,8,9,10);
    MathObservable.min(observable).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer value) {
            Log.e(TAG,"最小值为"+value);
        }
    });
}
log:


count操作符

count操作符是计算被观察者发送了多少条数

public void count(View view){
    Observable
            .just(1,2,3,4,5,6,7,8,9,10)
            .count()
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer count) {
                    Log.e(TAG,"发送了多少个数据"+count);
                }
            });
}
log:


sum操作符

sum就是计算发送数据中队列的值的总和,他有四个操作符,分别是sumInteger,sumLong,sumDouble,sumFloat

public void sum(View view){
    Observable observable  = Observable.just(1,2,3,4,5,6,7,8,9,10);
    MathObservable.sumInteger(observable).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer value) {
            Log.e(TAG,"总和为"+value);
        }
    });
}
log:


onErrorReturn操作符

在rxjava中,当程序遇到异常的时候,给我们提供了三个catch异常的操作符,onErrorReturn是其中一个,

public void onErrorReturn(View view){
    Observable
            .create(new OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("消息1----");
                subscriber.onNext("消息2----");
                subscriber.onError(new NullPointerException("我擦,空指针异常了,怎么写的代码,这么低级的错误"));
                subscriber.onCompleted();
              }
           })
            .onErrorReturn(new Func1<Throwable, String>() {
                @Override
                public String call(Throwable throwable) {
                    return "程序异常了,发送一个默认的消息";
                }
            })
            .subscribe(new Observer<String>() {
            @Override
            public void onCompleted() {
                Log.e(TAG,"onCompleted--------------");
            }
            @Override
            public void onError(Throwable e) {
                Log.e(TAG,"异常信息="+e.getLocalizedMessage());
            }
            @Override
            public void onNext(String s) {
                Log.e(TAG,s);
            }
    });
}
log:


你会发现虽然程序发生了异常,但是程序并没有挂掉,是因为我们catch了这个异常,然后发送了一个默认的消息给观察者,而且onError()回调中也没有接受到异常,因为被拦截了.

结论:onErrorReturn 捕获异常,并发送一个默认的消息

onErrorResumeNext操作符

onErrorResumeNext操作符也是捕获程序发生的异常,该方法返回的被观察者就会重新订阅观察者并接受消息

public void onErrorResumeNext(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("消息1----");
                    subscriber.onNext("消息2----");
                    subscriber.onError(new NullPointerException("我擦,空指针异常了,怎么写的代码,这么低级的错误"));
                    subscriber.onCompleted();
                }
            })
            .onErrorResumeNext(Observable.create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("程序出现了异常发送一个空消息");
                }
            }))
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                    Log.e(TAG,"onCompleted--------------");
                }
                @Override
                public void onError(Throwable e) {
                    Log.e(TAG,"异常信息="+e.getLocalizedMessage());
                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,s);
                }
            });
}
log:


onExceptionResumeNext操作符

public void onExceptionResumeNext(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("消息1----");
                    subscriber.onNext("消息2----");
                    subscriber.onError(new NullPointerException("我擦,空指针异常了,怎么写的代码,这么低级的错误"));
                    subscriber.onCompleted();
                }
            })
            .onExceptionResumeNext(Observable.create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("程序出现了异常发送一个空消息");
                }
            }))
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                    Log.e(TAG,"onCompleted--------------");
                }
                @Override
                public void onError(Throwable e) {
                    Log.e(TAG,"异常信息="+e.getLocalizedMessage());
                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,s);
                }
            });
}
log:


retry操作符

retry操作符就是在发生异常的时候进行重试,如果调用不带参数的retry()方法,他会一直重试,直到成功为止,比我网络异常我们一般就会进行重试,

Observable
        .create(new OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("请求服务器详情接口----");
                subscriber.onError(new TimeoutException("请求超时了"));
            }
        })
        .retry(2)
        .subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.e(TAG,s);
            }
        });
log:


这是请求了三次,重试了2次+本身执行1次

异常log:


这个时候刚好可以配合上面讲的异常操作符进行catch,就不至于程序挂掉,如果你写代码每对其进行异常的catch的话,那么就这么写,程序也不会挂

Observable
        .create(new OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("请求服务器详情接口----");
                subscriber.onError(new TimeoutException("请求超时了"));
            }
        })
        .retry(2)
        .subscribe(new Observer<String>() {
            @Override
            public void onCompleted() {
            }
            @Override
            public void onError(Throwable e) {
                Log.e(TAG,"异常-"+e.getLocalizedMessage());
            }
            @Override
            public void onNext(String s) {
                Log.e(TAG,s);
            }
        });
所以平时开发还是用这个比较好.


observeOn操作符

指定观察者所在的线程,比如你要请求网络,就指定让他在子线程,要更新UI就指定在主线程也就是所说的UI线程

public void observeOn(View view){
    Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("发送消息");
            Log.e(TAG,"被观察者所在的线程名字是="+Thread.currentThread().getName());
        }
    }).subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"观察者所在的线程名字是="+Thread.currentThread().getName());
        }
    });
观察者和被观察者默认所在的线程是你调用这段代码所在的线程,我是在主线程中,现在打log看下:


这就验证了上面的说法,如果你观察者是对IO操作,那么就需要放在子线程中,比如网络请求后读流什么的,就是需要observeOn这个操作符了

public void observeOn(View view){
    Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("发送消息");
            Log.e(TAG,"被观察者所在的线程名字是="+Thread.currentThread().getName());
        }
    })
    .observeOn(Schedulers.io())
    .subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"观察者所在的线程名字是="+Thread.currentThread().getName());
        }
    });
}
log:


现在看到了观察者所在的线程是在子线程中了,而不是默认和他所调的线程是同一个线程了.如果想要观察者在主线程中就使用这个observeOn(AndroidSchedulers.mainThread())

当然了还提供了其他线程 如图:



subscribeOn操作符

subscribeOn操作符是指定被观察者和观察者所在的线程

public void subscribeOn(View view){
    Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("发送消息");
            Log.e(TAG,"被观察者所在的线程名字是="+Thread.currentThread().getName());
        }
    })
            .subscribeOn(Schedulers.io())
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"观察者所在的线程名字是="+Thread.currentThread().getName());
                }
            });
}
log:


如果你想要观察者在主线程中执行并更新UI的话就这么做

public void subscribeOn(View view){
    Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("发送消息");
            Log.e(TAG,"被观察者所在的线程名字是="+Thread.currentThread().getName());
        }
    })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"观察者所在的线程名字是="+Thread.currentThread().getName());
                }
            });
}
log:


ok,达到了我们的需求

线程调度器

所谓调度器就是你想让某个业务放在特定的线程中执行,比如在子线程或者主线程或者是开启一个新的子线程

public void thread_scheduler(View view){
    //在子线程中创建一个执行任务 可以看作一个Thread或者Runnable
   final Scheduler.Worker worker =  Schedulers.io().createWorker();
    worker.schedule(new Action0() {
        @Override
        public void call() {
            //在这执行你的业务 这个call方法所在线程就是子线程
            //........
            worker.unsubscribe();
        }
    });
}
一般在这个call()线程中执行完毕后,为了节省内存一般要解绑订阅


DoOnEach操作符

doOnEach操作符对流的监听也是对观察者中onNext(),onError(),onCompleted()方法的监听,比如你有个需求当知道马上要调用onCompleted()方法的时候蛋个toast就可以在这个doOnEach()的onCompleted()方法中去做

public void doOnEach(View view){
    Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("现在事件是"+System.currentTimeMillis());
            subscriber.onCompleted();
        }
    }).doOnEach(new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"开始执行观察者中的onCompleted方法");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"开始执行观察者中的onNext方法");
        }
    }).subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"接收到消息是:"+s);
        }
    });
}
log:


doOnNext操作符

对观察者中的doOnNext()事件进行监听

public void doOnNext(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("现在事件是"+System.currentTimeMillis());
                    subscriber.onCompleted();
                }
            })
            .doOnNext(new Action1<String>() {
                @Override
                public void call(String s) {
                    Log.e(TAG,"开始执行观察者中的onNext方法");
                }
            })
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"接收到消息是:"+s);
                }
            });
}
log:


对应的还有doOnError(),doOnCompleted()对错误和完成的监听

doOnSubscribe操作符

监听什么时候开始订阅的,一般配合delay操作符使用比较好

public void doOnSubscribe(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("现在事件是"+System.currentTimeMillis());
                    subscriber.onCompleted();
                }
            })
            .doOnSubscribe(new Action0() {
                @Override
                public void call() {
                    Log.e(TAG,"开始订阅");
                }
            })
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"接收到消息是:"+s);
                }
            });
}
log:


如果使用了delay操作符延迟的话,其实他是在订阅之前调用的,不行你试试

doOnUnsubscribe操作符

doOnUnsubscribe是当观察者和被观察者之间解除了绑定的回调,如果你只发送了onNext()事件,这个解除监听是监听不到的,一定要发送onCompleted事件,这个时候才有用,

public void doOnUnsubscribe(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("现在事件是"+System.currentTimeMillis());
                    subscriber.onCompleted();
                }
            })
            .doOnUnsubscribe(new Action0() {//解绑订阅的监听
                @Override
                public void call() {
                    Log.e(TAG,"解绑订阅了");
                }
            })
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {
                    Log.e(TAG,"收到onCompleted事件");
                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"接收到消息是:"+s);
                }
            });
}
log:


serialize操作符

serialize操作符强制一个Observable连续调用onNext()事件并保证他正确,啥意思?也就是说一个Observable可能异步调用他的观察者方法,可能会导致Observable行为不正确,他可能会在某个onNext调用之前尝试调用onCompleted或者onError方法(也就是发送事件),或者从二个不同的线程中去调用onNext(),使用serialize操作符可以让Ovservable行为正确而且是同步的

也就是说你在onCompleted事件发送后还发送了onNext()事件这个是就容易出问题,但是我们平常用到的订阅(subscribe)在其调用发送onCompleted后确实也不发送了onNext事件啊,这个时候就要用到不安全的订阅,配合serialize操作符使用才更好说明问题

public void serialize(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(final Subscriber<? super String> subscriber) {
                    subscriber.onNext("请客户端等待");
                    subscriber.onCompleted();
                    new Thread(){
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(3000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            subscriber.onNext("去后台请求一个接口,返回一个json,大概耗时10");
                        }
                    }.start();
                    subscriber.onCompleted();
                }
            })
            .unsafeSubscribe(new Subscriber<String>(){//不安全的订阅
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,s);
                }
            });
}
你会看到我调用了onCompleted事件后又发送了一个延迟的onNext事件,看看能不能收到

log


你会看到还是会发送onNext事件啊,而且观察者也接收到了事件,这可能会出问题,为了防止出这种问题,就要使用serialize操作符了,现在我们添加serialize操作符,再看看打印的log

public void serialize(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(final Subscriber<? super String> subscriber) {
                    subscriber.onNext("请客户端等待");
                    subscriber.onCompleted();
                    new Thread(){
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(3000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            subscriber.onNext("去后台请求一个接口,返回一个json,大概耗时10");
                        }
                    }.start();
                    subscriber.onCompleted();
                }
            })
            .serialize()
            .unsafeSubscribe(new Subscriber<String>(){//不安全的订阅
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,s);
                }
            });
}
log:


你会看到当发送了onCompleted事件后在子线程中调用了onNext事件并没有发送出去.


timeout操作符

这是在某个时间段还没发送消息的话,就可以使用这个超时,

public void timeout(View view){
    Observable
            .create(new OnSubscribe<String>() {
                @Override
                public void call(final Subscriber<? super String> subscriber) {
                    subscriber.onNext("网络请求成功了");
                }
            })
            .delay(4,TimeUnit.SECONDS)//模拟网络请求
            .timeout(2,TimeUnit.SECONDS)
            .subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {
                    Log.e(TAG,"异常超时了");
                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,s);
                }
            });
}
log:


Using操作符

using操作符是用于创建一次资源,用完后就释放,像android一些系统资源,比如cursor,必须用完记得close等 这个意思

using函数有三个形参,看下它的方法

public static <T, Resource> Observable<T> using(
        final Func0<Resource> resourceFactory,
        final Func1<? super Resource, ? extends Observable<? extends T>> observableFactory,
        final Action1<? super Resource> disposeAction) {
    return using(resourceFactory, observableFactory, disposeAction, false);
}
如果英文好的人看它的注释就知道了

第一个参数:用于创建一次性资源的工厂函数

第二个参数:用于创建一次性Observable的工厂函数

第三个参数:用于释放资源的函数

public void using(View view){
    Observable observable = Observable.using(new Func0<String>() {
        @Override
        public String call() {
            return "返回一个cursor对象,记得用完要close";
        }
    }, new Func1<String, Observable<?>>() {
        @Override
        public Observable<?> call(String s) {//s就是一次性资源 通过Observable发送事件
            return Observable.just(s);
        }
    }, new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,"要销毁这个资源");//在这里资源我们是用字符串模拟了
            s = null;
        }
    });
    observable.subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"事件完毕onCompleted");
        }
        @Override
        public void onError(Throwable e) {
        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"接收到的消息是:::"+s);
        }
    });
}
log:


buffer操作符

被观察者和观察者可能存在不同的线程之间,有的时候可能被观察者发送的数据很快,这个时候观察者可能来不及处理发送过来的事件从而导致这个事件接收不到而被抛弃了,buffer操作就是减少这种观察者接收不到事件而抛弃,是减少,不是完全解决,

public void buffer(View view){
    Observable observable = Observable.just("章子怡","范冰冰","刘茹英","刘德华","梁朝伟");
    Observable<List<String>> bufferObservable = observable.buffer(2);//缓存2    bufferObservable.subscribe(new Observer<List<String>>() {
        @Override
        public void onCompleted() {
            Log.e(TAG,"onCompleted:::");
        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(List<String> strings) {
            Log.e(TAG,"--------------华丽的分割线-----------");
            for(String str:strings){
                Log.e(TAG,"接收到的消息是:::"+str);
            }
        }
    });
}
log:


看到打印的log,发现他是根据你缓存的数量进行发送的,

结论:buffer是将发送的数据进行缓存,缓存到一定长度后统一发送,最后一个数据也会被发送

Window操作符

window操作符就是把被观察者根据window方法传递的数据分解成几个子观察者,然后发送数据

public void window(View view){
    Observable observable = Observable.just("章子怡","范冰冰","刘茹英","刘德华","梁朝伟");
    Observable<Observable<String>> windowObservable = observable.window(2);
    windowObservable.subscribe(new Observer<Observable<String>>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Observable<String> stringObservable) {
            Log.e(TAG,"stringObservable="+stringObservable);
            stringObservable.subscribe(new Observer<String>() {
                @Override
                public void onCompleted() {

                }
                @Override
                public void onError(Throwable e) {

                }
                @Override
                public void onNext(String s) {
                    Log.e(TAG,"--------------华丽的分割线-----------");
                    Log.e(TAG,"接收到事件="+s);
                }
            });
        }
    });
}

log:


与buffer不同,buffer操作符只有一个观察者,而window是有个子观察者

Map操作符

map操作符是将发送的数据进行修改或者转换吧,比如有这样一个需求,就是你后台某个的接口地址变了,要使用新的接口,就可以这么做

public void map(View view){
    Observable
        .create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("http://www.baidu.com");
         }
       })
       .map(new Func1<String, String>() {
                @Override
                public String call(String s) {
                    if(s.equals("http://www.baidu.com")){
                        return "http://www.qq.com";
                    }
                    return null;
                }
            })
        .subscribe(new Observer<String>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(String s) {
            Log.e(TAG,"你访问的网址是::"+s);
        }
    });
}
log:


你会发现我们把访问百度的连接改成了访问qq的连接.


scan操作符

是对发送的数据进行操作后的结果进行发送给观察者,他会把前面的结果只+本次发送的数据

public void scan(View view){
    Observable.just(1,5,10,15,20)
            .scan(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer i1, Integer i2) {
                    return i1+i2;
                }
            }).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer integer) {
            Log.e(TAG,integer+"");
        }
    });
}
log:


默认是会发送一次的,也就是说第一次发送一个1,可以把前面看做发送了一个0

cast操作符

强制要求发送数据的类型,比如post请求time,对应的字段要求传递一个long值,但是别人不知道,这个时候就可以使用cast操作符,传递其他的就报错

public void cast(View view){
    Observable.create(new OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("11111");

        }
    }).cast(String.class).subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,s);
        }
    });

}

toList操作符

把发送的数据放到一个集合中,然后返回这个列表

public void toList(View view){
    Observable.just(1,2,3,4,5).toList().subscribe(new Action1<List<Integer>>() {
        @Override
        public void call(List<Integer> integers) {
            for(Integer i:integers){
                Log.e(TAG,i+"");
            }
        }
    });
}
log:


toSortedList操作符

对发送多个数据进行排序

public void toSortedList(View view){
    Observable
            .just(2,4,1,3,5)
            .toSortedList()
            .subscribe(new Action1<List<Integer>>() {
        @Override
        public void call(List<Integer> integers) {
            for(Integer i:integers){
                Log.e(TAG,i+"");
            }
        }
    });
}
log:


默认他是升序,如果你想降序排序呢,

public void toSortedList(View view){
    Observable
            .just(2,4,1,3,5)
            .toSortedList(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer integer, Integer integer2) {
                    return integer2-integer;
                }
            })
            .subscribe(new Action1<List<Integer>>() {
        @Override
        public void call(List<Integer> integers) {
            for(Integer i:integers){
                Log.e(TAG,i+"");
            }
        }
    });
}
log:


有点像Java中Comparable

toMap操作符

tomap就是把发送的数据进行转成map,key可以自己自定义

public void toMap(View view){
    Observable
        .just("time","sort","name","pwd")
        .toMap(new Func1<String, String>() {
            @Override
            public String call(String s) {
                return s;
            }
        }).subscribe(new Action1<Map<String, String>>() {
        @Override
        public void call(Map<String, String> stringStringMap) {
            for (Map.Entry<String, String> entry: stringStringMap.entrySet()) {
                Log.e(TAG,"key="+entry.getKey()+"::"+"value="+entry.getValue());
            }
        }
    });
}
log:


toMultiMap操作符

这个和tomap操作符很像,不同的是value变成一个集合

public void toMultiMap(View view){
    Observable
            .just("time","sort","name","pwd")
            .toMultimap(new Func1<String, String>() {
                @Override
                public String call(String s) {
                    return s;
                }
            }).subscribe(new Action1<Map<String, Collection<String>>>() {
        @Override
        public void call(Map<String, Collection<String>> stringCollectionMap) {
            Log.e(TAG,"stringCollectionMap="+stringCollectionMap);
        }
    });
}
log:



flatMap操作符

将发送的数据进行转换你想要的数据后,再发送数据,但是创建了多个Observable,

public void flatMap(View view){
    Observable.just(1,2,3,4,5)
            .flatMap(new Func1<Integer, Observable<Integer>>() {
                @Override
                public Observable<Integer> call(final Integer integer) {
                    return Observable.create(new OnSubscribe<Integer>() {
                        @Override
                        public void call(Subscriber<? super Integer> subscriber) {
                            subscriber.onNext(integer*2+10);
                        }
                    });
                }
            }).subscribe(new Observer<Integer>() {
        @Override
        public void onCompleted() {

        }
        @Override
        public void onError(Throwable e) {

        }
        @Override
        public void onNext(Integer value) {
            Log.e(TAG,"value="+value);
        }
    });
}
log:


flatMapIterable操作符

将发送的数据进行变换后生成一个Iterable再发送给观察者

public void flatMapIterable(View view){
    Observable.just(1,2,3,4,5)
            .flatMapIterable(new Func1<Integer, Iterable<String>>() {
                @Override
                public Iterable<String> call(Integer integer) {
                    return Arrays.asList(integer*2+"");
                }
            }).subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
            Log.e(TAG,"value="+s);
        }
    });
}
log:


concatMap操作符

连续发送多个事件,让他按顺序发送

public void concatMap(View view){
    Observable
            .from(getPersons())
            .concatMap(new Func1<Person, Observable<String>>() {
                @Override
                public Observable<String> call(Person person) {
                    return Observable.just(person.getName());
                }
            })
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    Log.e(TAG,"value="+s);
                }
            });
}
public List<Person> getPersons(){
    List<Person>  persons = new ArrayList<>();
    persons.add(new Person("章子怡","34183987778925",40));
    persons.add(new Person("范冰冰","34183986678925",35));
    persons.add(new Person("刘茹英","341839855558925",30));
    persons.add(new Person("刘茹英","341839855558925",35));
    return persons;
}
log:


groupBy操作符

按照某个条件分组发送数据,比如我们在数据库存的Person对象,sex是性别,女为奇数,男为偶数

public void groupBy(View view){
    Observable
            .just(1,2,3,4,5)
            .groupBy(new Func1<Integer, String>() {
        @Override
        public String call(Integer integer) {
            return integer%2==0?"":"";
        }
    })
            .subscribe(new Action1<GroupedObservable<String, Integer>>() {
        @Override
        public void call(final GroupedObservable<String, Integer> stringIntegerGroupedObservable) {
            stringIntegerGroupedObservable.subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    Log.e(TAG,stringIntegerGroupedObservable.getKey()+":"+integer.toString()); //偶数:2,奇数:3...
                }
            });
        }
    });
}

log:


就写到了吧,太累 需要休息!如果哦看完这个,且手动练习的话,至少说rxjava你会用了

github:https://github.com/zhouguizhi/RxjavaDemo

猜你喜欢

转载自blog.csdn.net/coderinchina/article/details/78638503