RxJava 源码解读

本文详细解读了RxJava的基本概念、源码实现,包括观察者(Subscriber)、被观察者(Observable)及其相关接口,如Function、Action、OnSubscribe、Operator、Transformer等。还深入探讨了订阅(subscribe)、线程切换的Scheduler机制,如observeOn和subscribeOn的实现原理。最后,文章提到了Single、Completable和Subject等特殊类型,并简要总结了RxJava的重要特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明本文出自maplejaw的博客(http://blog.csdn.net/maplejaw_

开源库地址:https://github.com/ReactiveX/RxJava
解读版本:1.1.8

基本概念

RxJava 是一个基于Java的响应式扩展实现: 即一个通过使用可观察序列来编写异步和基于事件的程序库。
它扩展了观察者模式以支持数据/事件序列,您可以根据声明好的规则通过操作符将序列组合在一起,而不用去担心低级别的线程,同步,线程安全和并发数据结构的各种问题。

基本用法

前面既然说了RxJava扩展了观察者模式,也就是说,RxJava是采用观察者模式实现的。既然是观察者模式,那么一定需要两个东西,被观察者和观察者。
怎么初始化一个观察者?(以下例子以订阅String类型为例子)
我们可以直接使用Observer来初始化,Observer是一个接口,里面有onNext,onCompleted,onError三个抽象方法。

  Observer<String> observer=new Observer<String>() {
            @Override
            public void onCompleted() {
                //正常终止时调用,onError和onCompleted只会通知一个
            }

            @Override
            public void onError(Throwable e) {
              //当Observable遇到错误或者无法返回期望的数据时会调用这个方法,后续不会再调用onNext和onCompleted
            }

            @Override
            public void onNext(String s) {
             //Observable调用这个方法发射数据
            }
        };

此外我们可以使用Observer的子类Subscriber来初始化。Subscriber相对于Observer增加了onStartunsubscribe,事实上,即使你使用的是Observer,在内部仍然会被包装为Subscriber

        Subscriber<String> subscriber=new Subscriber<String>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {

            }
        };

怎么初始化一个被观察者?
初始化被观察者使用Observable,在call内进行处理事件。可以看出call的参数为Subscriber,这也进一步证实了Observer会被包装为Subscriber。只要被观察者调用call方法,订阅者就可以接受到事件/数据了。

  Observable<String> observable=Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("hello");
                subscriber.onNext("welcome to china");
                subscriber.onCompleted();
            }
        });

那么问题来了,怎么建立一个订阅关系?
只需被观察者调用Observable.subscribe(Subscriber)即可。
于是整个流程是这样的。

     //被观察者
     Observable<String> observable=Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("hello");
                subscriber.onNext("welcome to china");
                subscriber.onCompleted();
            }
        });

    //观察者  
    Observer<String> observer=new Observer<String>() {
            @Override
            public void onCompleted() {
             Log.d("JG","onCompleted");
            }

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

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

      //被观察者订阅观察者(实际应理解为观察者订阅被观察者。)
      observable.subscribe(observer);

运行结果如下。
image_1alc28ectmnu1nev16p11ibb1vs59.png-12.6kB

此外,该库还有非常完善的异常捕获机制,当在处理数据时发生异常,可以自动捕获并回调到onError中。将observable修改成如下后,进行测试:

Observable<String> observable=Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                //...
                throw  new RuntimeException();//模拟抛出异常
            }
        });

测试结果如下:
image_1app9gp8iic0pbg1f7ilad1dhh9.png-4.1kB

OK,基本用法已经介绍完了,接下来,本篇将深入源码内部一探究竟(操作符相关内容将在下一篇单独介绍,如果只对操作符感兴趣敬请期待下篇)。如果你只是刚接触RxJava,请看给 Android 开发者的 RxJava 详解这篇文章。

源码解读

观察者(Subscriber)

Subscriber提供了一种从被观察者接收推送数据和通知以及从被观察者中取消订阅的机制。
实现了Observer和Subscription接口,在Observer的基础上加入了onStart生命周期方法。该类属性如下:

public abstract class Subscriber<T> implements Observer<T>, Subscription {
   
    private static final long NOT_SET = Long.MIN_VALUE;//未设置请求数量
    private final SubscriptionList subscriptions;//订阅列表,一个存放订阅者(实现了Subscription接口)的列表,以便一同解除订阅
    private final Subscriber<?> subscriber;//订阅者

    private Producer producer;//生产者(用来处理反压),被观察和观察者之间的请求通道

    private long requested = NOT_SET; //请求数, 默认为Long.MIN_VALUE。

    protected Subscriber() {
        this(null, false);
    }

 protected Subscriber(Subscriber<?> subscriber, boolean shareSubscriptions) {
        this.subscriber = subscriber;
        //是否共享订阅列表
        this.subscriptions = shareSubscriptions && subscriber != null ? subscriber.subscriptions : new SubscriptionList();
    }
    //..
    //省略了部分源码
    }

从源码可以看出Subscriber内部包含了一个子Subscriber,可以共享同一个订阅列表。Producer用于建立被观察者和观察者间的可以指定请求数量的请求通道,一般用来配合解决反压问题(backpressure)。Producer是一个函数式接口,里面就一个抽象方法void request(long n);SubscriptionList是一个订阅列表,以便将多个订阅者一起取消订阅。
关于设置Producer和请求数的源码如下:
request(long n)

    protected final void request(long n) {
        if (n < 0) {
  //必须大于等于0
            throw new IllegalArgumentException("number requested cannot be negative: " + n);
        } 

        Producer producerToRequestFrom = null;
        synchronized (this) {
            if (producer != null) {
                producerToRequestFrom = producer;
            } else {
            //没有producer的话就保存到Subscriber的requested值,会逐渐累加。
                addToRequested(n);
                return;
            }
        }
        //如果有producer就直接调用Producer的request。
        producerToRequestFrom.request(n);
    }

setProducer


    public void setProducer(Producer p) {
        long toRequest;//请求数
        boolean passToSubscriber = false;//是否传递给子Subscriber
        synchronized (this) {
            toRequest = requested;//赋值之前保存的请求数
            producer = p;//赋值给producer
            if (subscriber != null) {
  //内部Subscriber不为空
                if (toRequest == NOT_SET) {
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值