RxJava 源码解读

转载请注明本文出自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) {
  
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java源码包实例源码JAVA开发源码50个合集: Ajax框架 ZK.rar Java图书馆管理系统源程序.rar Java图片倒影效果实例源码.rar Java图片翻折,将图像压扁.rar Java坦克大战网络对战版源代码.rar Java声音播放程序源代码.rar JAVA实现CLDC与MIDP底层编程的代码.rar Java实现HTTP连接与浏览,Java源码下载.rar Java实现的FTP连接与数据浏览程序.rar Java实现的放大镜效果附有源文件.rar Java实现的点对点短消息发送协议(smpp)开发包源码.rar Java实现的视频播放程序源码.rar Java实现移动的遮照效果.rar JAVA实现超级玛丽.zip Java实现跟踪鼠标运行坐标的源码.rar Java手机与计算机互发彩信源码.rar Java手机游戏大富翁源代码+注释.rar Java手机短信项目源码.rar Java扫雷源码.rar Java生成自定义控件源代码.rar Java调色板面板源代码.rar Java跳棋(基于SWT).rar Java通讯录手机版源码.rar Java鼠标拖拽功能.rar 乐趣大型购物系统.rar 可实现网上对战和人机对战.rar 基于BS结构的Java可视化工作流定制软件.rar 基于J2ME的Java游戏梦幻炸弹人源程序.rar 基于JAVA的ICQ系统.rar 基于Java的mp3播放器源代码.rar 基于Java的小型人事管理系统,带数据库.rar 基于JAVA的日程提醒簿.rar 基于Java的邮件服务器源程序.rar 基于MVC的Java资源管理器 v2.0.rar 基于smpp协议的Java点对点短信发送源码包.rar 季风进销存管理系统(JSP版).rar 客户管理系统 Alfresco Content Management.rar 家庭多媒体播放器.rar 局域网广播系统java源码.rar 开源Winzip压缩工具Java源码.rar 很不错的Java计算器.rar 很强的Java加密解密算法源码.rar 泡泡堂战车游戏JAVA源码.rar 简单模拟的J2ME潜艇大战源代码.rar 简单的注册与登录功能.rar 类似QQ的聊天软件JAVA源码(附设计文档).rar 进程通信.rar 连接postsql数据库的java代码.rar 附加数据库.rar 雷电游戏JAVA版源程序.rar

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值