一. Rxjava是什么

  Rxjava在GitHub的介绍是 "A library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 JVM上使用可观测的序列来组成异步的、基于事件的程序的库)。

Rxjava是一个采用了观察者模式设计处理异步的基于事件机制的框架。另外,链式调用、逻辑简单清晰。

看下rxjava无背压模式的简单用法:

 Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {

             @Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("Hello the world");
}
}); observable.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) { } @Override
public void onNext(String s) { } @Override
public void onError(Throwable e) { } @Override
public void onComplete() { }
});

1. 创建一个Observable,重写subscribe方法,这里主要处理被观察的事件。
2. 订阅这个Observable,事件会回调observer的方法,可以对事件做响应的处理

二. 无背压模式的源码解析

2.1. 创建Observable:

创建Observable用的是Observable.create(ObservableOnSubscribe<T> source)方法。这个方法的参数是ObservableOnSubscribe:

public interface ObservableOnSubscribe<T> {

    /**
* Called for each Observer that subscribes.
* @param e the safe emitter instance, never null
* @throws Exception on error
*/
void subscribe(@NonNull ObservableEmitter<T> e) throws Exception;
}

ObservableOnSubscribe是一个函数式接口,有唯一的方法subscribe,参数是ObservableEmitter<T> e。ObservableEmitter是一个继承了Emitter的接口,接口Emitter里定义了onNext、onError、onComplete等方法,和Observer(观察者)的方法相对应。

public interface Emitter<T> {

    /**
* Signal a normal value.
* @param value the value to signal, not null
*/
void onNext(@NonNull T value); /**
* Signal a Throwable exception.
* @param error the Throwable to signal, not null
*/
void onError(@NonNull Throwable error); /**
* Signal a completion.
*/
void onComplete();
}

ObservableEmitter对接口Emitter进行扩展,增加了setDisposable、setCancellable等方法
下面看看create方法:

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}

调用了RxJavaPlugins的onAssembly方法。又有一个新参数ObservableCreate<T>(source),我们看看它是什么:

final class ObservableCreate<T> extends Observable<T> {

    public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
} }

继承了Observable,是被观察对象,在构造函数中我们看到我们new ObservableOnSubscribe对象,被存在了ObservableCreate source引用里

onAssembly方法:

public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}

一个Hook方法。onObservableAssembly是一个静态变量,没有设置默认为空,所以直接返回source对象。也就是说,Observable的create方法其实就是把ObservableOnSubscribe对象存储在ObservableCreate对象的source引用里,然后返回该ObservableCreate对象。
ObservableCreate是继承Observable的,所以创建了ObservableCreate对象,Observable也就创建完了。

2.2 订阅事件(被观察者)

订阅操作是observable.subscribe(new Observer<String>())。这里是被观察者订阅观察者,主要是因为链式调用方便,因为subscribe方法里的参数Observer才是观察者。我们也会在Observer里的各个被调方法里接收到事件相关的返回值。
subscribe订阅方法的源码:

  public final void subscribe(Observer<? super T> observer) {
try {
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
RxJavaPlugins.onError(e);
}
}

实际上调用了subscribeActual(observer);,这个方法是Observable里的方法,而此时的Observable是一个ObservableCreate对象。ObservableCreate里面的subscribeActual如下:

protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent); try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}

方法主要做了三件事:

1. 创建一个CreateEmitter对象parent;
2. 把parent传给source的subscribe方法,也就是ObservableOnSubscribe对象的subscribe方法:

@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("a");
}

所以在这个方法里就能收到一个CreateEmmiter,通过CreateEmitter可以回调相应的方法。CreateEmitter是实现ObservableEmitter接口,内部onNext源码如下:

@Override
public void onNext(T t) {
observer.onNext(t);
}

也就是说,当我们在ObservableOnSubscribe的subscribe方法里调用ObservableEmitter的onNext方法的时候,它里面会调用observer的onNext。于是通过这样的传递就能在observer的回调方法里收到。

总结无背压Rxjava(observable/observer):

1、使用Observbable.create方法,产生一个ObservableCreate对象,对象里存着ObservableOnSubscribe对象source。

2、调用ObservableCreate.subscribe方法,实际调用的是subscribeActual方法,传入一个Observer对象。

3、subscribeActual方法中创建一个CreateEmmiter对象,调用source.subscribe方法,传入CreateEmmiter对象。

4、于是我们在ObservableOnSubscribe中就接收到了一个CreateEmmiter,CreateEmmiter是ObservableEmmiter的子类。我们可以在这里调用CreateEmmiter的方法进行事件回调。

5、调用CreateEmmiter方法,实际上会调用Observer的响应的方法。也就是CreateEmmiter把事件状态传递给观察者。

rxJava2.x源码解析的更多相关文章

  1. Android进阶:五、RxJava2源码解析 2

    上一篇文章Android进阶:四.RxJava2 源码解析 1里我们讲到Rxjava2 从创建一个事件到事件被观察的过程原理,这篇文章我们讲Rxjava2中链式调用的原理.本文不讲用法,仍然需要读者熟 ...

  2. Android进阶:四、RxJava2 源码解析 1

    本文适合使用过Rxjava2或者了解Rxjava2的基本用法的同学阅读 一.Rxjava是什么 Rxjava在GitHub 主页上的自我介绍是 "a library for composin ...

  3. RxJava2 源码解析(二)

    概述 承接上一篇RxJava2 源码解析(一),本系列我们的目的: 知道源头(Observable)是如何将数据发送出去的.    知道终点(Observer)是如何接收到数据的.    何时将源头和 ...

  4. RxJava2 源码解析(一)

    概述 最近事情太多了,现在公司内部的变动,自己岗位的变化,以及最近决定找工作.所以博客耽误了,准备面试中,打算看一看RxJava2的源码,遂有了这篇文章. 不会对RxJava2的源码逐字逐句的阅读,只 ...

  5. RxJava2源码解析(二)

    title: RxJava2源码解析(二) categories: 源码解析 tags: 源码解析 rxJava2 前言 本篇主要解析RxJava的线程切换的原理实现 subscribeOn 首先, ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  7. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  8. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  9. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

随机推荐

  1. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  2. FTP安装及配置

    在centos7安装ftp服务 yum install -y vsftpd 启动服务 systemctl start vsftpd 自启动 systemctl enable vsftpd 查看端口 注 ...

  3. STM32F429的新版用户手册更新记录, 改进、交流(2019-08-18发布V0.9版本)

    2019-06-16 发布首版V0.1 2019-06-23 发布V0.2版本 新增章节: 第3章 STM32F429 整体把控 第4章 STM32F429 工程模板建立(MDK5) 第5章 STM3 ...

  4. jQuery-跨域问题的处理

    调用登录接口时,后端一般会在调用登录接口成功后,在response中设置cookie,之后前端的每次请求都会自动地在请求头上加上后端设置好的cookie,这对前端来说是透明的. 当登录接口与登录后调用 ...

  5. Redis缓存与数据库一致性解决方案

    背景 缓存是数据库的副本,应用在查询数据时,先从缓存中查询,如果命中直接返回,如果未命中,去数据库查询最新数据并返回,同时写入缓存. 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载.是应用架 ...

  6. 软件测试价值提升之路- 第二章"价值实现的起点"读书笔记

    价值实现的起点 2.1 打破常规 打破哪些已经不适应现在软件开发需要的“准则”,明确需要在什么样的环境下.瞄准什么目标来实现测试的价值 找风险:研发内部测试 测试最基础的是找bug,但需要根据风险找最 ...

  7. 急速下载pandas

    使用国内源进行下载: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua ...

  8. 16套java架构师,高并发,高可用,高性能,集群,大型分布式电商项目实战视频教程

    16套Java架构师,集群,高可用,高可扩展,高性能,高并发,性能优化,设计模式,数据结构,虚拟机,微服务架构,日志分析,工作流,Jvm,Dubbo ,Spring boot,Spring cloud ...

  9. [转]UiPath: How to Capture a Mouse Event on Hover Menus?

    本文转自:https://www.uipath.com/kb-articles/how-to-capture-mouse-event-on-hover-menus he Knowledgebase a ...

  10. 使用docker-compose部署springboot项目

    由于是单机测试,没有测试多主机的跨网络分布式请求. 项目是前后分离的,所以使用nginx作为前端服务器,后端是springboot则直接基于java8环境的容器上跑,cache用的redis,mysq ...