上个月RxJava 2正式发布,然而国内相关资料仍较为匮乏。熟悉RxJava 1的开发者可通过更新日志快速上手,但对于从未接触过该框架的初学者而言,却面临选择困惑:是先学习旧版还是直接切入新版?为帮助这些新手顺利入门,本文特别撰写此教程,系统介绍RxJava 2的核心概念与基本用法,助力开发者跨越学习门槛,快速掌握响应式编程的基本技能。
1、 学习RxJava2无需先掌握RxJava1,两者虽有关联,但2是全新设计,可直接上手。
2、 类似论坛常讨论的学Java前是否要先学C语言,这类问题容易引发争议,此处不作争论。(毕竟PHP才是最好的语言!)
3、 答案显然是否定的。如果你曾接触过RxJava1,只需了解其更新内容即可,因为RxJava2的核心理念并未改变。对于未学习过RxJava1的读者也无需担忧,完全可以直接从RxJava2入手。因此,本教程中所涉及的所有概念和术语均基于RxJava2,不会引入任何RxJava1的内容,确保学习过程清晰且专注。
4、 在Android项目中集成RxJava2,需先在Gradle文件中添加相应依赖配置。
5、 正题
6、 学习前,先了解一些基本原理。
7、 网上关于RxJava原理的文章很多,大多从观察者模式讲起,先介绍观察者、被观察者以及订阅关系等概念,内容繁杂。初读时,这些术语让我感到困惑,花了很长时间才理清它们之间的逻辑。或许是我理解能力有限,难以一下子领会这些抽象名词背后的深意,总感觉入门门槛有点高,学起来颇为吃力。
8、 今天我用两根水管来比喻观察者与被观察者,通过事件流的视角,以通俗易懂的方式讲解RxJava的基本工作原理,帮助理解两者之间的数据传递关系。
9、 假设有两根水管。
10、 上方的水管为事件发起方,称为上游;下方的水管为事件接收方,称为下游。
11、 两根水管以特定方式相连,确保上游每发生一个事件,下游便能立即接收到。与官网事件图方向相反,此处事件发送顺序为先1、再2、再3,接收顺序同样如此。这种设计更贴近日常思维习惯,逻辑清晰,便于理解,整个过程直观明了,有助于快速掌握事件流动的规律。
12、 上游对应RxJava中的Observable,下游对应Observer,二者通过subscribe()建立连接。这种数据流关系在RxJava中可通过订阅机制清晰表达,形成完整的事件传递链条。
13、 创建一个上游的可观察对象。
14、 }
15、 });
16、 建立一个用于接收数据的观察者。
17、 }
18、 }
19、 }
20、 }
21、 };
22、 建立连接通道
23、 运行结果如下:
24、 只有在上下游建立连接,即调用 subscribe() 方法后,上游才会开始发送事件。
25、 将代码串联起来,便形成了RxJava独特的链式调用风格。
26、 下面介绍两个新概念:ObservableEmitter 与 Disposable,它们在响应式编程中扮演重要角色。
27、 ObservableEmitter 是一个事件发射器,顾名思义,它用于发送各类事件信号。该发射器支持三种事件类型:通过调用 onNext(T value) 方法发送下一个数据项,表示事件流中的有效数据;调用 onComplete() 表示事件序列正常结束,不再发出更多数据;调用 onError(Throwable error) 则表明事件流中出现异常,终止后续操作并传递错误信息。这三种方法共同构成了响应式编程中事件发射的核心机制,确保数据流能够被正确、完整地通知给订阅者。
28、 需遵循特定规则,不可随意无序发送事件。
29、 上游可连续发送多个数据,下游亦能持续接收这些数据流。
30、 上游发送onComplete后,其后续事件仍会继续发出;但下游一旦接收到onComplete,便会停止接收之后的所有事件。
31、 上游发出onError后,其后续事件仍会继续发送;而下游一旦接收到onError,便会停止接收之后的所有事件。
32、 上游可以选择不发送完成或错误信号。
33、 最关键的是onComplete与onError必须保持唯一且互不相容,既不能多次发送onComplete,也不能多次发送onError,更不允许先发出onComplete再发出onError,或相反顺序执行,两者只能择一触发,确保流程的严谨性与状态的一致性。
34、 关于onComplete与onError必须唯一且互斥的要求,需开发者在编码过程中自行保证。若逻辑上违反该原则,并不一定会立即引发程序崩溃。例如,连续发送多个onComplete事件,系统通常只会处理第一个,后续的将被忽略,程序仍可正常运行。然而,若触发多次onError事件,情况则不同:在接收到第二个错误信号时,极有可能导致程序异常终止或崩溃。因此,务必确保错误事件仅被发出一次,避免重复调用,以维持流的稳定性与正确性。
35、 上述规则的示意图如下所示。
36、 接下来介绍Disposable,这个词原意指可一次性使用、用后即弃的物品。在RxJava中,可以将其理解为连接两根数据流管道之间的控制开关。当调用其dispose()方法时,这个开关便会切断上下游之间的连接,使事件无法继续向下传递,下游因此不再接收到任何数据。它常用于实现资源的及时释放和防止内存泄漏,尤其在观察者订阅关系中起到关键的解绑作用,确保不再需要时能够主动终止事件流的传递。
37、 调用dispose()不会阻止上游继续发送事件,上游仍会持续发出剩余的事件,需注意事件流的完整处理。
38、 以一个示例说明:上游依次发送1、2、3、complete、4,当下游接收到第二个数据后断开连接,观察实际运行结果。
39、 }
40、 }).
41、 }
42、 }
43、 }
44、 }
45、 }
46、 });
47、 运行结果显示:
48、 从运行结果可以看出,在接收到onNext 2事件后,水管被切断,但上游依然继续发送了3、complete和4等事件,并未因发出onComplete而终止。这表明上游操作并未真正停止。同时,下游的onSubscribe方法在所有事件之前最早被调用,说明订阅过程始终是事件流开始的第一步。
49、 Disposable的作用远不止如此,待后续讲解线程调度时,其重要性将更加凸显。随着学习的深入,我们会在更多场景中频繁遇到它的应用,逐步体会到它在实际开发中的关键价值与广泛用途。
50、 subscribe() 方法有多种重载形式,适用于不同场景。
51、 前文已介绍带Observer参数的方法,此处重点说明其余几种方法的具体用途与实现方式。
52、 调用无参的subscribe()表示下游不关注具体事件,上游可直接发送数据,无需考虑接收方的处理情况。
53、 当方法接收一个Consumer参数时,表示下游仅处理onNext事件,对其它事件忽略不计。因此,若只需响应onNext,可采用此种写法,简洁明了地处理数据流中的元素。
54、 其他方法类似,此处不再逐一说明。
55、 本次教程就到这里,谢谢观看。
