RxJava简介

本文为前段时间学习RxJava时留下的历史遗留笔记,仅作纪念,科学的大神教学帖子在这里-> 给 Android 开发者的 RxJava 详解

通过链式调用序列实现基于事件流的异步编程库。

核心思想是把一切重复化的(尤其多重嵌套异步)调用逻辑转换为基于事件(数据)流传递过程的观察者模式。

优势在于便捷安全的多种线程切换策略,构建异步事件逻辑,通过事件流(数据流)的切面分解实现逻辑平面化,解除多重异步回调的深层嵌套(Callback Hell)。

可在任意复杂场合下保持O(1)的链式结构复杂度,替换AsyncTask / Handler 等异步接口,而后者的结构复杂度往往是O(n)级的嵌套调用。

主要概念

Observable

被观察者,事件发送方,如杂志

  • create(OnSubscribe) 最基本的事件发送构造器,用于定义事件(异步)发送序列(通过异步API回调观察者方法)

  • from(Iterable / T[]) create的便捷变体方法,从数组或迭代器类型中读取数据

  • just(T..) create的便捷变体方法,从可变长参数中读取数据,事件序列为依次onNext发送每个实参,最后onCompleted()结束

  • filter(Func1<T, Boolean>) 过滤事件,返回false的事件将被抛弃

  • map(Func) 事件参数类型映射变换器,可将输入的事件参数类型通过自定义函数解析变换为另一实体类型

  • flatMap(Func) 事件参数类型分解映射变换器,可将输入的单个事件类型解析、分解、变换为一个新的次级Observable对象(包含可发送不定量异步事件),直观上是把每个单一事件映射为每一组新的(异步)事件,用于事件分解或插入新的异步操作

  • lift(Operator) 一切操作器(map、flatMap等)的实际工作函数,RxJava不推荐直接使用,仅限理解工作原理

  • compose(Transformer) 作业编排器,用于将多重Observable变换过程(map、flatMap、lift等组合)通用化为单一可重用作业对象,减少代码重复

  • subscribe(Observer / Action..) 执行订阅,或者称为subscribeBy被订阅更合乎思维逻辑,指定事件接收器

  • doOnSubscribe(Action) 预初始化,基于lift方法在subscribe调用时upstream回溯过程中被执行,运行在subscribeOn指定的线程中

  • doOnNext(Action) Subscriber.onNext执行前进行额外的操作,无返回

map、flatMap等变换通过lift函数实现,将产生一个包裹前一级observable对象的新observable(及对应的包裹subscriber),进行逐级调用上层OnSubscribe发送事件

  • subscribeOn(Scheduler) 指定发送事件的线程,影响doOnSubscribe以及Observable.create代码块(onSubscribe.call())。基于OnSubscribe.call()进行线程切换。
  • observeOn(Scheduler) 指定Observer(或下级变换处理产生的包裹Observer)执行事件处理逻辑(onNext或事件变换等)的线程,可依据需要多次指定切换每个处理过程所工作的线程。基于lift()在Subscriber的动作(onNext等)上进行线程切换。

subscribeOn指定的事件发送线程从upstream流向downstream过程中维持不变,直到遇到第一个observeOn为止,若不指定observeOn,则事件变换、消费过程将运行在上次指定的subscribeOn线程中。依据upstream回溯流向,subscribeOn从前一个Operator开始改变上游的执行线程。

Observer

Observer(观察者,事件接收、处理方,如读者)

|- Subscriber(订阅者,Observer接口的抽象类,实际上更常用这个类)

Observer

  • onNext(T) 在构建Observable时定义的OnSubscribe中指定发送事件所需回调的主要方法
  • onComplete() 所有onNext事件发送完毕(序列处理完毕)时进行回调的通知方法
  • onError(Throwable) 事件序列中途处理异常时回调的通知方法,此后不再发送事件

Subscriber

  • onStart() 预初始化,subscribe()订阅瞬间触发的通知方法,与subscribe()执行时所在线程相同
  • unsubscribe() 取消订阅,用于onPause() onStop() 等方法中,及时解除引用防止内存泄露

ActionX

半成品的观察者,仅拥有一个包含X个参数的call方法,用于单独定义Observer中的onNext / onComplete等方法,通过组合方式进行订阅

Action0 onCompleteAction = new ..{.. call(){ Log(complete) } };
Action1<Throwable> onErrorAction = new ..{.. call(Throwable e){ Log(error) } };
Action1<T> onNextAction = new ..{.. call(T t){ Log(next event) } };

FuncX

变换函数接口,仅拥有一个包含X个参数的call方法,用于定义输入事件类型的变换结果类型,如从String到URL、Bitmap或Observable类型

Func1<String, Bitmap>{
// 从Sring类型的路径参数解析出Bitmap对象
public Bitmap call(String path) {
.. return bitmap;
}
}

Scheduler

线程调度器,指定每个环节执行的线程

Schedulers.immediate() 默认调度器,在当前线程下执行
Schedulers.newThread() 无条件开启新线程执行
Schedulers.io() 使用IO线程池执行,线程池大小无上限
Schedulers.computation() 使用计算型线程池执行,线程池大小为CPU核心数量
AndroidSchedulers.mainThread() Android的主线程(UI线程)

发布事件流程

observable.subscribe(observer/subscriber)  // 注册观察者
-> subscriber.onStart // 观察者onStart方法在subscribe()相同线程上被立即执行
-> this.onSubscribe.call(subscriber) // 调用创建observable时构建的onSubscribe对象的call方法 // onSubscribe.call方法内,在upstream时通过subscribeOn指定的线程执行事件发送
// onNext内部的事件消费代码则在observeOn指定的线程中执行
-> subscriber.onNext(event); ..
-> subscriber.onCompleted();

使用方法小例

Observer订阅:

Observable.create(onSubscribe).subscribe(observer);

ActionX订阅:

observable.subscribe(onNextAction[, onErrorAction[, onCompleteAction]]);

doOnSubscribe初始化:

observable.
.subscribeOn(Schedulers.io()) // 指定 doOnSubscribe() 在 IO 线程初始化
.doOnSubscribe(new Action..)
.subscribeOn(AndroidSchedulers.mainThread()) // 指定在主线程发送事件
.subscribe(subscriber);

Scheduler调度:

observable
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.subscribe(..);

map变换:

Observable
.just(pathStr) // 事件类型为String
.map(new Func1<String, Bitmap>() { .. }) // 事件类型变换为Bitmap
.subscribe(new Action1<Bitmap>() { .. }); // 接收处理Bitmap类型事件

Scheduler多次调度:

observable
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(Schedulers.newThread()) // 指定下级map变换的线程为新开线程
.map(..) // 在新线程中变换
.observeOn(Schedulers.io()) // 指定下级map变换的线程为IO线程
.map(..) // 在IO线程中变换
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.subscribe(..);

compose作业编排:

Transformer<ParamType, ResultType> processAll = new ..{
public Observable<ResultType> call(Observable<ParamType> observable) {
return observable.map1().map2().flatMap1().lift1()..;
}
}

// 以下每个observable都将执行processAll定义的变换过程

observable1.compose(processAll).subscribe(observer1);
observable2.compose(processAll).subscribe(observer2);
observable3.compose(processAll).subscribe(observer3);
observable4.compose(processAll).subscribe(observer4);

相关其他开源库

  • Retrofit异步网络库充分解耦的API,原生内置对RxJava的支持
  • Volley可考虑RxVolley库,相当于RxJava+Volley集成版
  • RxAndroid仅保留AndroidSchedulers,提供一些UI线程等的切换入口
  • RxLifecycle(从RxAndroid分离)提供BindActivity和BindFragment方法,可在Activity或者Fragment结束的时候自动通知被观察者停止发出新的事件。
  • RxBinding(从RxAndroid分离)用于以可扩展的方式绑定View各种事件监听器
  • RxPreferences(从RxAndroid分离)用于监听SharedPreferences的变化
  • RxBus模式,是一种基于RxJava实现的EventBus模式

参考

给 Android 开发者的 RxJava 详解

RxJava学习资料集合

RxJava官方指南

Rx组织官方指南:各种事件流操作方法解释列表

用一张图解释RxJava中的线程控制

RxJava简介的更多相关文章

  1. RxJava RxAndroid【简介】

    资源 RxJava:https://github.com/ReactiveX/RxJava RxAndroid :https://github.com/ReactiveX/RxAndroid 官网:h ...

  2. RxJava简单的介绍

    1. RxJava简介 Rx(ReactiveX,响应式编程)是一种事件驱动的基于异步数据流的编程模式,整个数据流就像一条河流,它可以被观测(监听),过滤,操控或者与其他数据流合并为一条新的数据流.而 ...

  3. Android中使用反应式编程RxJava

    GitHut 地址: https://github.com/ReactiveX/RxAndroid (1)RxJava简介: RxJava 是一个在Java虚拟机上实现的响应式扩展库:提供了基于obs ...

  4. RxJava的使用

    前言 RxJava及RxAndroid比较详细的介绍可以参考该文档<给 Android 开发者的 RxJava 详解> 基本介绍 ReactiveX 及 RxJava使用大部分来自和参考& ...

  5. Android RxJava

    GitHut 地址: https://github.com/ReactiveX/RxAndroid build.gradle: compile 'io.reactivex:rxandroid:1.2. ...

  6. RxAndroid结合Retrofit,看看谁才是最佳拍档!

    这篇博文酝酿好久了,今天终于下定决心开始写!RxAndroid和Retrofit都算是当下非常流行的Android开发框架,这两个框架光是单独使用就已经爽歪歪了,那么将RxAndroid和Retrof ...

  7. 分享一份非常强势的Android面试题

    马上步入金九银十了,是时候看一些面试题去鹅厂了,接下来我将分享一些面试题,每天总结一点点,希望对大家有所帮助! ListView和RecyclerView区别 参考链接: https://blog.c ...

  8. RxJava2 方法总结

    RxJava2 方法总结 看了许多讲解RxJava的文章,有些文章讲解的内容是基于第一个版本的,有些文章的讲解是通过比较常用的一些API和基础的概念进行讲解的. 但是每次看到RxJava的类中的几十个 ...

  9. 异步编程RxJava-介绍

    前言前段时间写了一篇对协程的一些理解,里面提到了不管是协程还是callback,本质上其实提供的是一种异步无阻塞的编程模式:并且介绍了java中对异步无阻赛这种编程模式的支持,主要提到了Future和 ...

随机推荐

  1. 2013MPD上海6.22 PM 陆宏杰:通往卓越管理的阶梯 & 6.23AM Ray Zhang 产品创新管理的十八般武艺

    MPD2天的内容,参加了5个课程,其中2个是管理的,分别是陆宏杰老师的<通往卓越管理的阶梯>和Ray Zhang大师的<产品创新管理的十八般武艺>.他们2个人都谈到了一个关于招 ...

  2. Windows环境下maven 安装与环境变量配置

    Maven是一个项目管理的Java 工具,在JavaEE中,我们可以使用Maven方便地管理团队合作的项目,现在我们在学习JavaEE框架,使用Maven可以管理类库,有效方便地供团队中的其他人员使用 ...

  3. 虚拟机LVM扩容

    1.先在Vmware上,把虚拟机硬盘做扩展 2.现在打开虚拟机发现系统的磁盘空间已经扩了,但是硬盘分区可用空间没变,还是原来的30G [root@localhost ~]# fdisk -l Disk ...

  4. 网站日志实时分析工具GoAccess使用

    网站日志实时分析工具GoAccess使用 系统环境CentOS release 5.5 (Final) GoAccess是一款开源的网站日志实时分析工具. GoAccess 的工作方式就是读取和解析 ...

  5. android使用微软雅黑字体

    android使用微软雅黑字体,需要下载字体 ttf文件 下载地址:http://download.csdn.net/detail/xiaoliu123586/9049815 放在assert,然后引 ...

  6. Android 开发框架

    Android 开发框架包括基本的应用功能开发.数据存储.网络访问三大块. 1 应用方面 一般而言,一个标准的Android 程序包括Activity.Broadcast Intent Receive ...

  7. css shorthand属性简写

    一.什么是shorthand 属性简写(shorthand)就是一次性声明一组相关的属性.好处呢当然是众所周知的,让css从臃肿无序升级为简洁有效具有高可读性. 大多数的人都使用属性简写,我也用,但是 ...

  8. 算法实践——Twitter算法面试题(积水问题)的线性时间解法

    问题描述:在下图里我们有不同高度的挡板.这个图片由一个整数数组所代表,数组中每个数是墙的高度.下图可以表示为数组(2.5.1.2.3.4.7.2).假如开始下雨了,那么挡板之间的水坑能够装多少水(水足 ...

  9. hdu 5862 Counting Intersections

    传送门:hdu 5862 Counting Intersections 题意:对于平行于坐标轴的n条线段,求两两相交的线段对有多少个,包括十,T型 官方题解:由于数据限制,只有竖向与横向的线段才会产生 ...

  10. 网页中插入FLASH(swf文件),并且让Flash不遮挡HTML元素

    一:网页中插入flash代码如下:  当然里面的很多属性可以去掉,根据具体的需求而定.  我们在网页中经常遇到播放flash,要正常播放flash就要用到OBJECT和EMBED这两个标签.鉴于火狐及 ...