RxJava的消息订阅和线程切换原理

本文深入探讨RxJava的消息订阅和线程切换原理,从观察者模式、消息订阅的创建与订阅过程,到线程切换的subscribeOn()和observeOn()的源码分析,揭示RxJava在异步编程中的关键机制。通过对Observable.create()、subscribeOn()、observeOn()等方法的详细解析,阐述了线程切换的实现过程,帮助开发者更好地理解和应用RxJava。
摘要由CSDN通过智能技术生成

0.版权声明

本文由玉刚说写作平台提供写作赞助,版权归玉刚说微信公众号所有
原作者:四月葡萄
版权声明:未经玉刚说许可,不得以任何形式转载

1.前言

本文主要是对RxJava的消息订阅和线程切换进行源码分析,相关的使用方式等不作详细介绍。

本文源码基于rxjava:2.1.14

2. RxJava简介

RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.

It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.

上面这段话来自于RxJava在github上面的官方介绍。翻译成中文的大概意思就是:

RxJava是一个在Java虚拟机上的响应式扩展,通过使用可观察的序列将异步和基于事件的程序组合起来的一个库。

它扩展了观察者模式来支持数据/事件序列,并且添加了操作符,这些操作符允许你声明性地组合序列,同时抽象出要关注的问题:比如低级线程、同步、线程安全和并发数据结构等。

简单点来说, RxJava就是一个使用了观察者模式,能够异步的库。

3. 观察者模式

上面说到,RxJava扩展了观察者模式,那么什么是观察模式呢?我们先来了解一下。

举个例子,以微信公众号为例,一个微信公众号会不断产生新的内容,如果我们读者对这个微信公众号的内容感兴趣,就会订阅这个公众号,当公众号有新内容时,就会推送给我们。我们收到新内容时,如果是我们感兴趣的,就会点进去看下;如果是广告的话,就可能直接忽略掉。这就是我们生活中遇到的典型的观察者模式。

在上面的例子中,微信公众号就是一个被观察者(Observable),不断的产生内容(事件),而我们读者就是一个观察者(Observer) ,通过订阅(subscribe)就能够接受到微信公众号(被观察者)推送的内容(事件),根据不同的内容(事件)做出不同的操作。

3.1 Rxjava角色说明

RxJava的扩展观察者模式中就是存在这么4种角色:

角色 角色功能
被观察者(Observable 产生事件
观察者(Observer 响应事件并做出处理
事件(Event 被观察者和观察者的消息载体
订阅(Subscribe 连接被观察者和观察者

3.2 RxJava事件类型

RxJava中的事件分为三种类型:Next事件、Complete事件和Error事件。具体如下:

事件类型 含义 说明
Next 常规事件 被观察者可以发送无数个Next事件,观察者也可以接受无数个Next事件
Complete 结束事件 被观察者发送Complete事件后可以继续发送事件,观察者收到Complete事件后将不会接受其他任何事件
Error 异常事件 被观察者发送Error事件后,其他事件将被终止发送,观察者收到Error事件后将不会接受其他任何事件

4.RxJava的消息订阅

在分析RxJava消息订阅原理前,我们还是先来看下它的简单使用步骤。这里为了方便讲解,就不用链式代码来举例了,而是采用分步骤的方式来逐一说明(平时写代码的话还是建议使用链式代码来调用,因为更加简洁)。其使用步骤如下:

  1. 创建被观察者(Observable),定义要发送的事件。
  2. 创建观察者(Observer),接受事件并做出响应操作。
  3. 观察者通过订阅(subscribe)被观察者把它们连接到一起。

4.1 RxJava的消息订阅例子

这里我们就根据上面的步骤来实现这个例子,如下:

        //步骤1. 创建被观察者(Observable),定义要发送的事件。
        Observable observable = Observable.create(new ObservableOnSubscribe<String>() {
   
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
   
                emitter.onNext("文章1");
                emitter.onNext("文章2");
                emitter.onNext("文章3");
                emitter.onComplete();
            }
        });
        
        //步骤2. 创建观察者(Observer),接受事件并做出响应操作。
        Observer<String> observer = new Observer<String>() {
   
            @Override
            public void onSubscribe(Disposable d) {
   
                Log.d(TAG, "onSubscribe");
            }

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

            @Override
            public void onError(Throwable e) {
   
                Log.d(TAG, "onError : " + e.toString());
            }

            @Override
            public void onComplete() {
   
                Log.d(TAG, "onComplete");
            }
        };
        
        //步骤3. 观察者通过订阅(subscribe)被观察者把它们连接到一起。
        observable.subscribe(observer);

其输出结果为:

onSubscribe
onNext : 文章1
onNext : 文章2
onNext : 文章3
onComplete

4.2 源码分析

下面我们对消息订阅过程中的源码进行分析,分为两部分:创建被观察者过程和订阅过程。

4.2.1 创建被观察者过程

首先来看下创建被观察者(Observable)的过程,上面的例子中我们是直接使用Observable.create()来创建Observable,我们点进去这个方法看下。

4.2.1.1 Observable类的create()
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
   
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

可以看到,create()方法中也没做什么,就是创建一个ObservableCreate对象出来,然后把我们自定义的ObservableOnSubscribe作为参数传到ObservableCreate中去,最后就是调用 RxJavaPlugins.onAssembly()方法。

我们先来看看ObservableCreate类:

4.2.1.2 ObservableCreate类
public final class ObservableCreate<T> extends Observable<T> {
   //继承自Observable
    public ObservableCreate(ObservableOnSubscribe<T> source) {
   
        this.source = source;//把我们创建的ObservableOnSubscribe对象赋值给source。
    }
}

可以看到,ObservableCreate是继承自Observable的,并且会把ObservableOnSubscribe对象给存起来。

再看下RxJavaPlugins.onAssembly()方法

4.2.1.3 RxJavaPlugins类的onAssembly()
    public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
   
        //省略无关代码
        return source;
    }

很简单,就是把上面创建的ObservableCreate给返回。

4.2.1.4 简单总结

所以Observable.create()中就是把我们自定义的ObservableOnSubscribe对象重新包装成一个ObservableCreate对象,然后返回这个ObservableCreate对象。
注意,这种重新包装新对象的用法在RxJava中会频繁用到,后面的分析中我们还会多次遇到。
放个图好理解,包起来哈~
被观察者.png

4.2.1.5 时序图

Observable.create()的时序图如下所示:
Observable.create()时序图.png

4.2.2 订阅过程

接下来我们就看下订阅过程的代码,同样,点进去Observable.subscribe()

4.2.2.1 Observable类的subscribe()
    public final void subscribe(Observer<? super T> observer) {
   
            //省略无关代码
            
            observer = RxJavaPlugins.onSubscribe(this, observer);

            subscribeActual(observer);
            
            //省略无关代码
    }

可以看到,实际上其核心的代码也就两句,我们分开来看下:

4.2.2.2 RxJavaPlugins类的onSubscribe()
    public static <T> Observer<? super T> onSubscribe(@NonNull Observable<T> source, @NonNull Observer<? super T> observer) {
   
        //省略无关代码
        
        return observer;
    }

跟之前代码一样,这里同样也是把原来的observer返回而已。
再来看下subscribeActual()方法。

4.2.2.3 Observable类的subscribeActual()
    protected abstract void subscribeActual(Observer<? super T> observer);

Observable类的subscribeActual()中的方法是一个抽象方法,那么其具体实现在哪呢?还记得我们前面创建被观察者的过程吗,最终会返回一个ObservableCreate对象,这个ObservableCreate就是Observable的子类,我们点进去看下:

4.2.2.4 ObservableCreate类的subscribeActual()
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
   
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        //触发我们自定义的Observer的onSubscribe(Disposable)方法
        observer.onSubscribe(parent);

        try {
   
            source.subscribe(parent);
        } catch (Throwable ex) {
   
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

可以看到࿰

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值