阅读更多

1顶
0踩

编程语言

转载新闻 浅谈RxJava与2.0的新特性

2016-09-05 09:41 by 副主编 mengyidan1988 评论(0) 有11398人浏览
本文转自:http://www.dieyidezui.com

简介
说起 RxJava ,相信诸多 Android 开发者都不会陌生。作为一个知名的响应式编程库,从前年开始逐渐变得火热,从小众到被众多 Android 开发者们广泛引入与流传,其在 GitHub 的仓库截止笔者写这篇文章时,已经有16400+个 star 。甚至有一些大牛专门为 Android 写了 RxJava 的适配库,如

为什么 RxJava 如此受到 Android 开发者们的欢迎。我想不外乎两个原因。 1. 异步 2. 链式操作

异步
对 Android 线程有所了解的朋友都知道, Android的 UI 绘制 与 事件响应是在主线程的,为了保证界面的流畅性,很多耗时操作如读写数据库、读写文件、请求网络,我们都会挪到异步线程去完成,再回调到主线程。当然在4.0以后主线程直接就不允许请求网络了。

在过去没有 RxJava 的时候,开发者一般都是通过 AsyncTask , Thread ,更好些的就是通过线程池来完成这些任务。而有了 RxJava 以后,简简单单的一句话就可以随意的切换线程,简直不用太舒服。

最典型的 RxJava 中的Observable类,提供了2个函数, 分别是subscribeOn与observeOn。前者可以切换被观察时的线程(如果说数据发射的线程不够严谨,数据并非一定在观察时发射的,尤其是开发者自定义OnSubscribe时),后者可以切换数据被消费时的线程。

举一个切换线程的例子:
Log.i("debug", Thread.currentThread().getName());  
Observable.empty()  
        .doOnCompleted(new Action0() {
            @Override
            public void call() {
                Log.i("debug", Thread.currentThread().getName());
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .doOnCompleted(new Action0() {
            @Override
            public void call() {
                Log.i("debug", Thread.currentThread().getName());
            }
        })
        .subscribe();   

这里我们没有任何数据,就仅仅发射了一个onComplete,但是在切换线程的代码中,我们增加了onComplte时要额外执行的代码,输出结果如下:
引用

08-27 10:47:41.173 6741-6741/com.dieyidezui.rxjavademo I/debug: main 
08-27 10:47:41.201 6741-6762/com.dieyidezui.rxjavademo I/debug: RxIoScheduler-2 
08-27 10:47:41.217 6741-6741/com.dieyidezui.rxjavademo I/debug: main 

这仅仅是简单的例子, RxJava 提供了很多便捷的操作符供我们使用,如map、filter、flatMap、merge、concat等。可见当熟练使用后对我们的编程效率确实有很大帮助。尤其是 MVP 模式, RxJava 与之结合可谓是”天作之合”。

链式操作
上面笔者演示的代码其实就是 RxJava 的典型使用方式:

1.发射数据源
2.中间操作
3.处理结果
其中中间操作包含诸多用法, 如果切换线程,变换数据等。

为什么我说链式操作很好。第一,链式逻辑替代深度回调逻辑,容易编写,不易出 BUG 。第二,RxJava 提供诸多了整体处理数据的操作符,非常实用。第三,配合 Java8 的 lambda 表达式,使代码简短优雅。

好了,对 RxJava 的介绍就此为止了。进阶用法、原理剖析以后会有专门的文章。对 RxJava 不熟悉的同学,建议先去看一下官方的 wiki 。链接: https://github.com/ReactiveX/RxJava/wiki

RxJava2.0
前天, RxJava终于发布了2.0 RC1 版本,一直关注于此的笔者立刻就进去尝鲜了。结合官方的介绍,笔者总结并翻译了一些与 1.x 的异同与大家分享。

包名与MAVEN依赖
首先要说的就是 RxJava 2和1是互相独立的。因此包名与 maven 的依赖也是不一样的,就类似于 OkHttp 3与2一样。 RxJava 2.x的依赖是全新的io.reactivex.rxjava2:rxjava:2.x.y,并且类处于该io.reactivex包名下,而不再是rx。

接口变化
RxJava2 是遵循Reactive Streams Specification的规范完成的,新的特性依赖其提供的4个基础接口。分别是
  • Publisher
  • Subscriber
  • Subscription
  • Processor

Flowable与Observable
新的实现叫做Flowable, 同时旧的Observable也保留了。因为在 RxJava1.x 中,有很多事件不被能正确的背压,从而抛出MissingBackpressureException。

举个简单的例子,在 RxJava1.x 中的 observeOn, 因为是切换了消费者的线程,因此内部实现用队列存储事件。在 Android 中默认的 buffersize 大小是16,因此当消费比生产慢时, 队列中的数目积累到超过16个,就会抛出MissingBackpressureException, 初学者很难明白为什么会这样,使得学习曲线异常得陡峭。

而在 2.0 中,Observable 不再支持背压,而Flowable 支持非阻塞式的背压。并且规范要求,所有的操作符强制支持背压。幸运的是, Flowable 中的操作符大多与旧有的 Observable 类似。
Single、Completable
Single 与 Completable 都基于新的 Reactive Streams 的思想重新设计了接口,主要是消费者的接口, 现在他们是这样的:
interface SingleObserver<T> {  
    void onSubscribe(Disposable d);
    void onSuccess(T value);
    void onError(Throwable error);
}

interface CompletableObserver<T> {  
    void onSubscribe(Disposable d);
    void onComplete();
    void onError(Throwable error);
}

Subscriber
对比一下 Subscriber:
public interface Subscriber<T> {  
    public void onSubscribe(Subscription s);
    public void onNext(T t);
    public void onError(Throwable t);
    public void onComplete();
}

我们会发现和以前不一样的是多了一个onSubscribe的方法,Subscription如下:

Subscription
public interface Subscription {  
    public void request(long n);
    public void cancel();
}

熟悉 RxJava 1.x 的朋友能发现, 新的Subscription更像是综合了旧的Producer与Subscription的综合体。他既可以向上游请求数据,又可以打断并释放资源。而旧的Subscription在这里因为名字被占,而被重新命名成了Disposable

Disposable
public interface Disposable {  
    void dispose();
    boolean isDisposed();
}

这里最大的不同就是这个onSubscribe,根据 Specification, 这个函数一定是第一个被调用的, 然后就会传给调用方一个Subscription,通过这种方式组织新的背压关系。当我们消费数据时,可以通过Subscription对象,自己决定请求数据。

这里就可以解释上面的非阻塞的背压。旧的阻塞式的背压,就是根据下游的消费速度,中游可以选择阻塞住等待下游的消费,随后向上游请求数据。而新的非阻塞就不在有中间阻塞的过程,由下游自己决定取多少,还有背压策略,如抛弃最新、抛弃最旧、缓存、抛异常等。

而新的接口带来的新的调用方式与旧的也不太一样, subscribe后不再会有 Subscription 也就是如今的 Disposable,为了保持向后的兼容, Flowable 提供了 subscribeWith方法 返回当前的Subscriber对象, 并且同时提供了DefaultSubscriber, ResourceSubscriber,DisposableSubscriber,让他们提供了Disposable接口, 可以完成和以前类似的代码:
ResourceSubscriber<Integer> subscriber = new ResourceSubscriber<Integer>() {  
    @Override
    public void onStart() {
        request(Long.MAX_VALUE);
    }

    @Override
    public void onNext(Integer t) {
        System.out.println(t);
    }

    @Override
    public void onError(Throwable t) {
        t.printStackTrace();
    }

    @Override
    public void onComplete() {
        System.out.println("Done");
    }
};

Flowable.range(1, 10).delay(1, TimeUnit.SECONDS).subscribe(subscriber);

subscriber.dispose();  

收回 create 方法权限
在RxJava 1.x 最明显的问题就是由于 create 的太过开放,导致其被开发者滥用,而不是学习使用提供的操作符。

并且用户对 RxJava 不够了解,导致各种各样的问题,如背压、异常处理等。

由于规范要求所有的操作符强制支持背压,因此新的 create 采用了保守的设计,让用户实现FlowableOnSubscribe接口,并选取背压策略,然后在内部实现封装支持背压,简单的例子如下:
Flowable.create((FlowableEmitter<Integer> emitter) -> {  
    emitter.onNext(1);
    emitter.onNext(2);
    emitter.onComplete();
}, BackpressureStrategy.BUFFER);

Functions可以抛出异常
新的ActionX、FunctionX的方法声明都增加了一个throws Exception,这带来了显而易见的好处,现在我们可以这样写:
Flowable.just("file.txt")  
.map(name -> Files.readLines(name))
.subscribe(lines -> System.out.println(lines.size()), Throwable::printStackTrace);

而在以前是不行的, 因为Files.readLines(name)会显式的抛出一个IOException。这样对 lambda 更加友好,而不必再去 try catch 。

Scheduler可以直接schedule
在以前是必须要先createWorker,用 Worker 对象去 shedule, 现在可以直接在Scheduler用这些方法:
public abstract class Scheduler {
    public Disposable scheduleDirect(Runnable task) { ... }
    public Disposable scheduleDirect(Runnable task, long delay, TimeUnit unit) { ... }
    public Disposable scheduleDirectPeriodically(Runnable task, long initialDelay, 
        long period, TimeUnit unit) { ... }
    public long now(TimeUnit unit) { ... }
    // ... rest is the same: lifecycle methods, worker creation
}

这算是一个小优化,方便开发者使用。

Observable的一些继承并入了Flowable中
如ConnectableObservable、BlockObservable等,这样可以直接在Flowable中写出这样的代码:
List<Integer> list = Flowable.range(1, 100).toList().blockingFirst(); 

其他修改
还有一些普通开发者不太在意的修改:
  • hook方式变化,现在可以通过提供接口在 runtime hook
  • 部分在 1.x 中 被标记@Beta、@Experimental的操作符现在合并到正式版里了
  • 由于类结构的变动,一些类名的变化

等其他变动。

结语
RxJava作为开源的经典之作,笔者一直都有所关注。后续笔者会继续为大家带来 RxJava的源码解析与进阶使用系列等。感谢大家的阅读,如有不知之处,欢迎讨论交流。

这里是笔者的个人博客地址: dieyidezui.com
1
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 浅谈 RxJava 与 2.0 的新特性

    作为一个知名的响应式编程库,从前年开始逐渐变得火热,从小众到被众多 Android 开发者们广泛引入与流传,其在 GitHub 的仓库截止笔者写这篇文章时,已经有16400+个 star 。甚至有一些大牛专门为 Android 写了 ...

  • Android RxJava第三弹之RxJava2.0尝鲜

    RxJava+Animation RxJava+Glide在Android RxJava第一弹之原理详解、使用详解、常用场景(基于Rxjava2.0)一文中我一直在说RxJava2.0,2.0在16年八九月份的时候新出来 ,让我们一探究竟吧引言 RxJ

  • 全面剖析Rxjava2.0的前世今生

    一 、Rxjava2.0的前世1. Rxjava是什么? 查阅了好多文档后,我给Rxjava的定义是这样子的:Rxjava就是在观察者模式的骨架下,通过丰富的操作符和便捷的异步操作来完成对于复杂业务的处理。即两个核

  • 浅谈LeakCanary2源码

    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-3' } 原理就是利用ContentProvider的特性,其onCreate方法会在Application的onCreate方法之前被系统调用。所以只需要在AndroidManifest...

  • 浅谈反应式架构:基本概念介绍

    2.2 同步编程 VS 异步编程 当谈到同步与异步时,就不得不提一下阻塞与非阻塞的概念,因为这两组概念很容易混淆。导致混淆的原因是它们在描述同一个东西,但是关注点不同。 阻塞与非阻塞关注方法执行时当前线程的...

  • h5新特性

     ...HTML5新特性浅谈 发表于2016/10/17 21:25:58 7809人阅读 分类: 前端 转载请注明出处: http://blog.csdn.net/gane_cheng/article/details/52819118 http://www.ganecheng....

  • 深入理解 RxJava2:前世今生(1)

    本系列文章适用于已经了解 RxJava 的读者,深入贯彻其原理,加深对其的认识。如果从未了解过 RxJava 的读者们,建议先熟悉它。 RxJava 0.x RxJava 最早是 Netflix 参照微软的 Rx.Net,在 Java 上实现一套类似的库,0...

  • android之解锁新技能,平常的应用开发会用到的东东(持续更新)android工作经验总结

    都会用到,混合开发最好,如果逻辑不太复杂使用mvc,复杂了就mvp啦,mvp可以参考: 浅谈 MVP in Android_鸿洋_的博客-CSDN博客_android mvp mvc参考(原理)(其实android的设计思想就是mvc,随便写的代码就是mvc的...

  • DeepSeek与AI幻觉-清华大学团队制作

    DeepSeek与AI幻觉-清华大学团队制作 一、什么是AI幻觉 (定义与基础概念) 二、DeepSeek为什么会产生幻觉 (聚焦特定AI模型的幻觉成因分析) 三、AI幻觉评测 (评估AI幻觉的频率、类型与影响的方法) 四、如何减缓AI幻觉 (解决方案与技术优化方向) 五、AI幻觉的创造力价值 (探讨幻觉在创新场景中的潜在益处,如艺术生成、灵感激发等)

  • 协同过滤算法商品推荐系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计

    协同过滤算法商品推荐系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 前台用户可以实现注册登录、商品浏览,在线客服,加入购物车,加入收藏,下单购买,个人信息管理,收货信息管理,收藏管理,评论功能。 后台管理员可以进行用户管理、商品分类管理、商品信息管理、订单评价管理、系统管理、订单管理。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。

  • MES系统数字化工厂解决方案.pptx

    MES系统数字化工厂解决方案.pptx

  • MUI调用照片以及裁剪和图库照片上传到服务器

    MUI调用照片以及裁剪和图库照片上传到服务器

  • ChatGPT付费创作系统V3.1.3独立版 WEB端+H5端+小程序端 (新增DeepSeek高级通道+新的推理输出格式)

    GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序, 是基于国外很火的ChatGPT进行开发的Ai智能问答小程序。这是一种基于人工智能技术的问答系统, 可以实现智能回答用户提出的问题。相比传统的问答系统,ChatGPT可以更加准确地理解用户的意图, 提供更加精准的答案。同时系统采用了最新的GPT3.5接口与GPT4模型,同时还支持型,文心一言,腾讯混元, 讯飞星火,通义千问,DeepSeeK,智普等等国内各种大模型,可以更好地适应不同的应用场景,支持站点无限多开, 可以说ChatGPT付费创作系统目前国内相对体验比较好的一款的ChatGPT及多接口软件系统。 新增接入DeepSeek-R1、DeepSeek-V3(Ollama自部署和第三方均支持)、高级通道增加DeepSeek、 支持AI接口输出的reasoning_content字段(新的推理输出格式)、更新模型库、修复导出Excel的bug等功能, 优化了云灵Midjourney接口,出图更快更稳定。小程序端变化不大该系统版本测试下来比较完美, 老版本升级时数据库结构同步下,同时把原来

  • 基于java的美食点餐管理平台设计的详细项目实例(含完整的程序,GUI设计和代码详解)

    内容概要:本文档详细介绍了一款基于Java技术的美食点餐管理平台的设计与实现。该平台旨在优化传统餐饮行业的服务流程,通过智能化的点餐系统、高效的订单处理、智能库存管理和数据分析等功能,为用户提供便捷高效的点餐体验,并提升餐厅管理效率和服务质量。系统涵盖了前端设计、后端开发、数据库设计等方面,采用了成熟的Java技术和现代Web开发框架,如Spring Boot、Vue.js或React,确保系统的高效性和稳定性。此外,文档还包括详细的用户界面设计、模块实现以及系统部署指南,帮助开发者理解和搭建该平台。 适合人群:具备一定的Java编程基础和技术经验的研发人员、IT从业者以及有意开发类似系统的企业和个人。 使用场景及目标:①为餐厅提供一个集点餐、订单处理、库存管理于一体的高效平台;②优化传统餐饮服务流程,提升客户服务体验;③利用大数据分析辅助决策,助力餐饮企业精细化运营;④通过集成多种支付方式和其他外部系统,满足多样化的商业需求。 其他说明:本项目不仅提供了完整的技术方案和支持文档,还针对实际应用场景提出了多个扩展方向和技术优化思路,旨在引导用户不断迭代和完善该平台的功能和性能。

  • 相场模拟与激光制造技术:选择性激光烧结、激光融覆中的凝固与枝晶生长研究,相场模拟与激光制造技术:选择性激光烧结、激光融覆及凝固过程中的枝晶生长研究,相场模拟 选择性激光烧结 激光融覆 凝固 枝晶生长

    相场模拟与激光制造技术:选择性激光烧结、激光融覆中的凝固与枝晶生长研究,相场模拟与激光制造技术:选择性激光烧结、激光融覆及凝固过程中的枝晶生长研究,相场模拟 选择性激光烧结 激光融覆 凝固 枝晶生长 ,相场模拟; 选择性激光烧结; 激光融覆; 凝固; 枝晶生长,相场模拟与激光工艺:枝晶生长的凝固过程研究

  • 基于ssh框架开发的厂区管理系统,集成增删改查功能。.zip

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

  • 关于加强新能源汽车安全管理涉及的法规标准分析.pptx

    关于加强新能源汽车安全管理涉及的法规标准分析.pptx

  • 基于SSM的校园二手交易平台.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

  • 机器学习课程设计——基于AdaBoost的银行用户逾期行为检测.zip

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

Global site tag (gtag.js) - Google Analytics