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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值