Rxjava

本文深入讲解RxJava的工作原理,包括观察者模式的扩展、事件序列的创建与传递、链式操作符的应用等核心概念。

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

Rxjava原理介绍

  • Rxjava原理 基于 一种扩展的观察者模式
  • Rxjava的扩展观察者模式中有4个角色:

img

角色作用类比
被观察者(Observable)产生事件顾客
观察者(Observer)接收事件,并给出响应动作厨房
订阅(Subscribe)连接 被观察者 & 观察者服务员
事件(Event)被观察者 & 观察者 沟通的载体菜式

img

RxJava

        // 1.创建被观察者Observable对象
        Observable <Integer> observable = Observable.create(new ObservableOnSubscribe <Integer>(){ 
          // create()是RxJava最基本的创造事件序列的方法
          //此处传入了一个OnSubscribe对象参数
          //当Observable被订阅时,OnSubscribe的call()方法会自动被调用,即事件序列就会依照设定依次被触发
          //即观察者会依次调用对应事件的复写方法从而响应事件
          //从而实现被观察者调用了观察者的回调方法&由被观察者向观察者的事件传递,即        观察者模式// 2.在复写的subscribe()里定义需要发送的事件            @Override             public void subscribe(ObservableEmitter <Integer> emitter)throws Exception {                 //通过ObservableEmitter类对象产生事件并通知观察者                // ObservableEmitter类介绍                    // a。定义:事件发射器







                    // b. 作用:定义需要发送的事件 & 向观察者发送事件
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        });

<--扩展:RxJava 提供了其他方法用于 创建被观察者对象Observable -->
// 方法1:just(T...):直接将传入的参数依次发送出来
  Observable observable = Observable.just("A", "B", "C");
  // 将会依次调用:
  // onNext("A");
  // onNext("B");
  // onNext("C");
  // onCompleted();

// 方法2:from(T[]) / from(Iterable<? extends T>) : 将传入的数组 / Iterable 拆分成具体对象后,依次发送出来
  String[] words = {"A", "B", "C"};
  Observable observable = Observable.from(words);
  // 将会依次调用:











```java

<--方式1:采用Observer 接口 -->
        // 1. 创建观察者 (Observer )对象
        Observer<Integer> observer = new Observer<Integer>() {
        // 2. 创建对象时通过对应复写对应事件方法 从而 响应对应事件

            // 观察者接收事件前,默认最先调用复写 onSubscribe()
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            // 当被观察者生产Next事件 & 观察者接收到时,会调用该复写方法 进行响应
            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "对Next事件作出响应" + value);
            }

            // 当被观察者生产Error事件& 观察者接收到时,会调用该复写方法 进行响应
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            // 当被观察者生产Complete事件& 观察者接收到时,会调用该复写方法 进行响应
            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        };

<--方式2:采用Subscriber 抽象类 -->
// 说明:Subscriber类 = RxJava 内置的一个实现了 Observer 的抽象类,对 Observer 接口进行了扩展

// 1. 创建观察者 (Observer )对象
Subscriber<String> subscriber = new Subscriber<Integer>() {

// 2. 创建对象时通过对应复写对应事件方法 从而 响应对应事件
            // 观察者接收事件前,默认最先调用复写 onSubscribe()
            @Override
            public void onSubscribe(Subscription s) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            // 当被观察者生产Next事件 & 观察者接收到时,会调用该复写方法 进行响应
            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "对Next事件作出响应" + value);
            }

            //当被观察者生产错误事件与观察者接收到时,会调用该复写方法进行响应
            @覆盖
            公共无效的onError(Throwable的发送){ 
                Log.d(TAG, “对错误事件作出响应”); 
            }             //当被观察者生产完成事件&观察者接收到时,会调用该复写方法进行响应            @覆盖            公共无效的onComplete(){                 Log.d(TAG, “对完整的事件作出响应”);             }         }; < - 特别注意:2种方法的区别,即订阅者抽象类与观察者接口的区别 - > //相同点:二者基本使用方式完全一致(实质上,在RxJava的订阅过程中,Observer总是会议先被转换成Subscriber再使用)//不同点:Subscriber抽象类对观察者接口进行了扩展,新增了两个方法:    // 1. onStart():在还未响应事件前调用,用于做一些初始化工作    // 2. unsubscribe():用于取消订阅。在该方法被调用后,观察者将不再接收和响应事件














    // 调用该方法前,先使用 isUnsubscribed() 判断状态,确定被观察者Observable是否还持有观察者Subscriber的引用,如果引用不能及时释放,就会出现内存泄露






<div class="se-preview-section-delimiter"></div>
通过订阅(Subscribe)连接观察者和被观察者
observable.subscribe(observer);
 // 或者 observable.subscribe(subscriber);
<-- Observable.subscribe(Subscriber) 的内部实现 -->

public Subscription subscribe(Subscriber subscriber) {
    subscriber.onStart();
    // 步骤1中 观察者  subscriber抽象类复写的方法,用于初始化工作
    onSubscribe.call(subscriber);
    // 通过该调用,从而回调观察者中的对应方法从而响应被观察者生产的事件
    // 从而实现被观察者调用了观察者的回调方法 & 由被观察者向观察者的事件传递,即观察者模式
    // 同时也看出:Observable只是生产事件,真正的发送事件是在它被订阅的时候,即当 subscribe() 方法执行时
}






<div class="se-preview-section-delimiter"></div>
// RxJava的链式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
        // 1. 创建被观察者 & 生产事件
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            // 2. 通过通过订阅(subscribe)连接观察者和被观察者
            // 3. 创建观察者 & 定义响应事件的行为
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG,“开始采用subscribe连接”);             ()
            ; 
//默认最先调用复写的onSubscribe()            @             Override public void onNext(Integer value){                 Log.d(TAG,“对Next事件”+ value +“作出响应”);             }             @Override             public void onError(Throwable e){                 Log.d(TAG,“对错误事件作出响应”);             }             @Override             public void onComplete(){                 Log.d(TAG,“对完成事件作出响应”);             }         });     } } 注:整体方法调用顺序:观察者.onSubscribe()>被观察者.subscribe()>观察者.onNext()>观察者。

























 方式1:分步骤实现

**步骤1:加入依赖**





<div class="se-preview-section-delimiter"></div>

```java
 compile 'io.reactivex.rxjava2:rxjava:2.0.1'
 compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

步骤2:直接在MainActivity.java中实现下述步骤

  1. 创建被观察者 (Observable )& 生产事件
  2. 创建观察者 (Observer )并 定义响应事件的行为
  3. 通过订阅(Subscribe)连接观察者和被观察者
public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Rxjava";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



// 步骤1:创建被观察者 Observable & 生产事件
// 即 顾客入饭店 - 坐下餐桌 - 点菜

        //  1. 创建被观察者 Observable 对象
        Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
            // 2. 在复写的subscribe()里定义需要发送的事件
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                // 通过 ObservableEmitter类对象产生事件并通知观察者
                // ObservableEmitter类介绍
                    // a. 定义:事件发射器
                    // b. 作用:定义需要发送的事件 & 向观察者发送事件
                emitter.onNext(1); 
                emitter.onNext(2); 
                emitter.onNext(3); 
                emitter.onComplete(); 
            } 
        }); //步骤2:创建观察者Observer并定义响应事件行为//即开厨房 - 确定对应菜式        Observer <Integer> observer = new Observer <Integer>(){             //通过复写对应方法来响应被观察者            @覆写            public void onSubscribe(Disposable d){                 Log.d(TAG,“开始采用subscribe连接”);             ()            ; //默认最先调用复写的onSubscribe()            @             Override public void onNext(Integer value){                 Log.d(TAG,“对Next事件”+ value +“作出响应”);

















            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        };


        // 步骤3:通过订阅(subscribe)连接观察者和被观察者
        // 即 顾客找到服务员 - 点菜 - 服务员下单到厨房 - 厨房烹调
        observable.subscribe(observer);
  • 测试结果

img

方式2:基于事件流的链式调用方式

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Rxjava";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

// RxJava的流式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
        // 1. 创建被观察者 & 生产事件
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            // 2. 通过通过订阅(subscribe)连接观察者和被观察者
            // 3. 创建观察者 & 定义响应事件的行为
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }
            // 默认最先调用复写的 onSubscribe()

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "对Next事件"+ value +"作出响应"  );
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }

        });
    }
}

观察者 Observer的subscribe()具备多个重载的方法

  public final Disposable subscribe() {}
    // 表示观察者不对被观察者发送的事件作出任何响应(但被观察者还是可以继续发送事件)

    public final Disposable subscribe(Consumer<? super T> onNext) {}
    // 表示观察者只对被观察者发送的Next事件作出响应
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {} 
    // 表示观察者只对被观察者发送的Next事件 & Error事件作出响应

    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
    // 表示观察者只对被观察者发送的Next事件、Error事件 & Complete事件作出响应

    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
    // 表示观察者只对被观察者发送的Next事件、Error事件 、Complete事件 & onSubscribe事件作出响应

    public final void subscribe(Observer<? super T> observer) {}
    // 表示观察者对被观察者发送的任何事件都作出响应

变换操作符

img

Map()

  • 作用
    对 被观察者发送的每1个事件都通过 指定的函数 处理,从而变换成另外一种事件

即, 将被观察者发送的事件转换为任意的类型事件。

img

 // 采用RxJava基于事件流的链式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {

            // 1. 被观察者发送事件 = 参数为整型 = 1、2、3
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);

            }
            // 2. 使用Map变换操作符中的Function函数对被观察者发送的事件进行统一变换:整型变换成字符串类型
        }).map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) throws Exception {
                return "使用 Map变换操作符 将事件" + integer +"的参数从 整型"+integer + " 变换成 字符串类型" + integer ;
            }
        }).subscribe(new Consumer<String>() {

            // 3. 观察者接收事件时,是接收到变换后的事件 = 字符串类型
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, s);
            }
        });

  • 测试结果

img

从上面可以看出,map() 将参数中的 Integer 类型对象转换成一个 String类型 对象后返回,同时,事件的参数类型也由 Integer 类型变成了 String 类型

FlatMap()

  • 作用:将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
  • 原理

    1. 为事件序列中每个事件都创建一个 Observable 对象;
    2. 将对每个 原始事件 转换后的 新事件 都放入到对应 Observable对象;
    3. 将新建的每个Observable 都合并到一个 新建的、总的Observable 对象;
    4. 新建的、总的Observable 对象 将 新合并的事件序列 发送给观察者(Observer

https://i-blog.csdnimg.cn/blog_migrate/165152e3df4d48a4e9d0cf459b4ba3ad.webp?x-image-process=image/format,png

// 采用RxJava基于事件流的链式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }

            // 采用flatMap()变换操作符
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("我是事件 " + integer + "拆分后的子事件" + i);
                    // 通过flatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
                    // 最终合并,再发送给被观察者
                }
                return Observable.fromIterable(list);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, s);
            }
        });

  • 测试结果

img

注:新合并生成的事件序列顺序是无序的,即 与旧序列发送事件的顺序无关

ConcatMap()

  • 作用:类似FlatMap()操作符
  • FlatMap()的 区别在于:拆分 & 重新合并生成的事件序列 的顺序 = 被观察者旧序列生产的顺序
  • 原理

https://i-blog.csdnimg.cn/blog_migrate/da2e4a09e2634a4ff1d66884044a86b5.webp?x-image-process=image/format,png

// 采用RxJava基于事件流的链式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }

            // 采用concatMap()变换操作符
        }).concatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("我是事件 " + integer + "拆分后的子事件" + i);
                    // 通过concatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
                    // 最终合并,再发送给被观察者
                }
                return Observable.fromIterable(list);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, s);
            }
        });

img

注:新合并生成的事件序列顺序是有序的,即 严格按照旧序列发送事件的顺序

Buffer()

  • 作用
    定期从 被观察者(Obervable)需要发送的事件中 获取一定数量的事件 & 放到缓存区中,最终发送
  • 原理

img

  • 应用场景

缓存被观察者发送的事件

// 被观察者 需要发送5个数字
        Observable.just(1, 2, 3, 4, 5)
                .buffer(3, 1) // 设置缓存区大小 & 步长
                                    // 缓存区大小 = 每次从被观察者中获取的事件数量
                                    // 步长 = 每次获取新事件的数量
                .subscribe(new Observer<List<Integer>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }
                    @Override
                    public void onNext(List<Integer> stringList) {
                        //
                        Log.d(TAG, " 缓存区里的事件数量 = " +  stringList.size());
                        for (Integer value : stringList) {
                            Log.d(TAG, " 事件 = " + value);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应" );
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

  • 测试结果

img

  • 过程解释

下面,我将通过一个图来解释Buffer()原理 & 整个例子的结果

https://i-blog.csdnimg.cn/blog_migrate/0924b75c673c1dcda2dafd9f57ad186a.webp?x-image-process=image/format,png

### 关于 RxJava 的使用指南和教程 #### 什么是 RxJavaRxJava 是一种基于响应式编程(Reactive Programming)的库,用于处理异步数据流。它通过观察者模式简化了复杂的异步操作,并提供了丰富的操作符来组合、转换和过滤数据流。 --- #### RxJava 的基本概念 RxJava 的核心组件包括以下几个部分: - **Observable/Flowable**: 数据源,表示可被订阅的数据流。 - **Observer/Subscriber**: 订阅者,接收来自 Observable 或 Flowable 的通知。 - **onNext()**: 接收正常的数据项。 - **onError()**: 处理错误情况。 - **onComplete()**: 表示数据流结束[^2]。 --- #### 如何开始使用 RxJava? ##### 添加依赖 要使用 RxJava,在项目的 `build.gradle` 文件中添加以下依赖: ```gradle implementation 'io.reactivex.rxjava3:rxjava:3.1.5' implementation 'io.reactivex.rxjava3:rxandroid:3.0.0' ``` 注意:上述版本号可能随时间更新,请查阅官方文档获取最新版本[^4]。 --- #### 基本使用方式 ###### 方法一:分步骤实现 这是为了深入了解 RxJava 的工作原理。以下是具体的步骤: 1. 创建一个 Observable 对象。 2. 定义 Observer 来监听事件。 3. 调用 subscribe() 方法将两者连接起来。 代码示例: ```java // 步骤1:创建Observable对象 Observable<String> observable = Observable.just("Hello", "World"); // 步骤2:定义Observer Observer<String> observer = new Observer<String>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(String value) { System.out.println(value); } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onComplete() { System.out.println("Completed"); } }; // 步骤3:建立订阅关系 observable.subscribe(observer); ``` ###### 方法二:链式调用 这种方式更适合实际项目中的简洁性和高效性。可以通过链式调用来完成复杂的操作: 代码示例: ```java Observable.just("Hello", "World") .map(s -> s.toUpperCase()) // 将字符串转为大写 .subscribe(System.out::println); // 输出结果 ``` --- #### 组合与合并操作符详解 RxJava 提供了许多强大的操作符来帮助开发者灵活地处理数据流。常见的组合与合并操作符如下: 1. **merge():** 合并多个 Observables 并保持顺序不固定[^1]。 ```java Observable.merge(Observable.just(1, 2), Observable.just(3, 4)) .subscribe(System.out::println); ``` 2. **concat():** 类似 merge,但会按顺序依次发射数据。 ```java Observable.concat(Observable.just(1, 2), Observable.just(3, 4)) .subscribe(System.out::println); ``` 3. **zip():** 将多个 Observables 发射的数据按照指定的方式组合在一起。 ```java Observable.zip( Observable.just("A", "B"), Observable.just("C", "D"), (s1, s2) -> s1 + "-" + s2) .subscribe(System.out::println); ``` --- #### Retrofit 结合 RxJava 使用 Retrofit 和 RxJava 可以很好地配合使用,从而简化网络请求流程。首先需要配置 Retrofit 支持 RxJava: 代码示例: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); // 定义接口 interface ApiService { @GET("/data") Observable<List<Data>> getData(); } ApiService apiService = retrofit.create(ApiService.class); // 执行请求 apiService.getData().subscribe(dataList -> { dataList.forEach(item -> System.out.println(item)); }, throwable -> { throwable.printStackTrace(); }); ``` --- #### 更多资源推荐 如果想进一步学习 RxJava,可以参考以下资料: - Carson_Ho 的《Android RxJava 实际应用教学》[^3]。 - 一份详细的 RxJava 学习指南[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值