`
gybin
  • 浏览: 269815 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

深入浅出RxJava(一:基础篇)

    博客分类:
  • Java
 
阅读更多

原文链接

RxJava正在Android开发者中变的越来越流行。唯一的问题就是上手不容易,尤其是大部分人之前都是使用命令式编程语言。但是一旦你弄明白了,你就会发现RxJava真是太棒了。
这里仅仅是帮助你了解RxJava,整个系列共有四篇文章,希望你看完这四篇文章之后能够了解RxJava背后的思想,并且喜欢上RxJava。

基础

RxJava最核心的两个东西是Observables(被观察者,事件源)和Subscribers(观察者)。Observables发出一系列事件,Subscribers处理这些事件。这里的事件可以是任何你感兴趣的东西(触摸事件,web接口调用返回的数据。。。)

一个Observable可以发出零个或者多个事件,知道结束或者出错。每发出一个事件,就会调用它的Subscriber的onNext方法,最后调用Subscriber.onNext()或者Subscriber.onError()结束。


Rxjava的看起来很想设计模式中的观察者模式,但是有一点明显不同,那就是如果一个Observerble没有任何的的Subscriber,那么这个Observable是不会发出任何事件的。

Hello World

创建一个Observable对象很简单,直接调用Observable.create即可
[java] view plaincopy
 
  1. Observable<String> myObservable = Observable.create(  
  2.     new Observable.OnSubscribe<String>() {  
  3.         @Override  
  4.         public void call(Subscriber<? super String> sub) {  
  5.             sub.onNext("Hello, world!");  
  6.             sub.onCompleted();  
  7.         }  
  8.     }  
  9. );  
这里定义的Observable对象仅仅发出一个Hello World字符串,然后就结束了。接着我们创建一个Subscriber来处理Observable对象发出的字符串。
[java] view plaincopy
 
  1. Subscriber<String> mySubscriber = new Subscriber<String>() {  
  2.     @Override  
  3.     public void onNext(String s) { System.out.println(s); }  
  4.   
  5.     @Override  
  6.     public void onCompleted() { }  
  7.   
  8.     @Override  
  9.     public void onError(Throwable e) { }  
  10. };  
这里subscriber仅仅就是打印observable发出的字符串。通过subscribe函数就可以将我们定义的myObservable对象和mySubscriber对象关联起来,这样就完成了subscriber对observable的订阅。
[java] view plaincopy
 
  1. myObservable.subscribe(mySubscriber);  
一旦mySubscriber订阅了myObservable,myObservable就是调用mySubscriber对象的onNext和onComplete方法,mySubscriber就会打印出Hello World!

更简洁的代码

是不是觉得仅仅为了打印一个hello world要写这么多代码太啰嗦?我这里主要是为了展示RxJava背后的原理而采用了这种比较啰嗦的写法,RxJava其实提供了很多便捷的函数来帮助我们减少代码。

首先来看看如何简化Observable对象的创建过程。RxJava内置了很多简化创建Observable对象的函数,比如Observable.just就是用来创建只发出一个事件就结束的Observable对象,上面创建Observable对象的代码可以简化为一行
[java] view plaincopy
 
  1. Observable<String> myObservable = Observable.just("Hello, world!");  
接下来看看如何简化Subscriber,上面的例子中,我们其实并不关心OnComplete和OnError,我们只需要在onNext的时候做一些处理,这时候就可以使用Action1类。
[java] view plaincopy
 
  1. Action1<String> onNextAction = new Action1<String>() {  
  2.     @Override  
  3.     public void call(String s) {  
  4.         System.out.println(s);  
  5.     }  
  6. };  
subscribe方法有一个重载版本,接受三个Action1类型的参数,分别对应OnNext,OnComplete, OnError函数。
[java] view plaincopy
 
  1. myObservable.subscribe(onNextAction, onErrorAction, onCompleteAction);  
这里我们并不关心onError和onComplete,所以只需要第一个参数就可以
[java] view plaincopy
 
  1. myObservable.subscribe(onNextAction);  
  2. // Outputs "Hello, world!"  
上面的代码最终可以写成这样
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.     .subscribe(new Action1<String>() {  
  3.         @Override  
  4.         public void call(String s) {  
  5.               System.out.println(s);  
  6.         }  
  7.     });  
使用java8的lambda可以使代码更简洁
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.     .subscribe(s -> System.out.println(s));  
Android开发中,强烈推荐使用retrolambda这个gradle插件,这样你就可以在你的代码中使用lambda了。

变换

让我们做一些更有趣的事情吧!
比如我想在hello world中加上我的签名,你可能会想到去修改Observable对象:
[java] view plaincopy
 
  1. Observable.just("Hello, world! -Dan")  
  2.     .subscribe(s -> System.out.println(s));  
如果你能够改变Observable对象,这当然是可以的,但是如果你不能修改Observable对象呢?比如Observable对象是第三方库提供的?比如我的Observable对象被多个Subscriber订阅,但是我只想在对某个订阅者做修改呢?
那么在Subscriber中对事件进行修改怎么样呢?比如下面的代码:
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.     .subscribe(s -> System.out.println(s + " -Dan"));  
这种方式仍然不能让人满意,因为我希望我的Subscribers越轻量越好,因为我有可能会在mainThread中运行subscriber。另外,根据响应式函数编程的概念,Subscribers更应该做的事情是“响应”,响应Observable发出的事件,而不是去修改。如果我能在某些中间步骤中对“Hello World!”进行变换是不是很酷?

操作符(Operators)

操作符就是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件。RxJava提供了很多很有用的操作符。
比如map操作符,就是用来把把一个事件转换为另一个事件的。
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.   .map(new Func1<String, String>() {  
  3.       @Override  
  4.       public String call(String s) {  
  5.           return s + " -Dan";  
  6.       }  
  7.   })  
  8.   .subscribe(s -> System.out.println(s));  
使用lambda可以简化为
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.     .map(s -> s + " -Dan")  
  3.     .subscribe(s -> System.out.println(s));  
是不是很酷?map()操作符就是用于变换Observable对象的,map操作符返回一个Observable对象,这样就可以实现链式调用,在一个Observable对象上多次使用map操作符,最终将最简洁的数据传递给Subscriber对象。

map操作符进阶

map操作符更有趣的一点是它不必返回Observable对象返回的类型,你可以使用map操作符返回一个发出新的数据类型的observable对象。
比如上面的例子中,subscriber并不关心返回的字符串,而是想要字符串的hash值
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.     .map(new Func1<String, Integer>() {  
  3.         @Override  
  4.         public Integer call(String s) {  
  5.             return s.hashCode();  
  6.         }  
  7.     })  
  8.     .subscribe(i -> System.out.println(Integer.toString(i)));  
很有趣吧?我们初始的Observable返回的是字符串,最终的Subscriber收到的却是Integer,当然使用lambda可以进一步简化代码:
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.     .map(s -> s.hashCode())  
  3.     .subscribe(i -> System.out.println(Integer.toString(i)));  
前面说过,Subscriber做的事情越少越好,我们再增加一个map操作符
[java] view plaincopy
 
  1. Observable.just("Hello, world!")  
  2.     .map(s -> s.hashCode())  
  3.     .map(i -> Integer.toString(i))  
  4.     .subscribe(s -> System.out.println(s));  

不服?

是不是觉得我们的例子太简单,不足以说服你?你需要明白下面的两点:

1.Observable和Subscriber可以做任何事情
Observable可以是一个数据库查询,Subscriber用来显示查询结果;Observable可以是屏幕上的点击事件,Subscriber用来响应点击事件;Observable可以是一个网络请求,Subscriber用来显示请求结果。

2.Observable和Subscriber是独立于中间的变换过程的。
在Observable和Subscriber中间可以增减任何数量的map。整个系统是高度可组合的,操作数据是一个很简单的过程。
分享到:
评论

相关推荐

    深入浅出程序设计竞赛(基础篇)部分题目链接-2021.02.20.pdf

    根据提供的文件信息,文件“深入浅出程序设计竞赛(基础篇)部分题目链接-2021.02.20.pdf”主要涉及的是程序设计竞赛相关的题目链接,标签“CSP-J NOIP 信奥”表明这些题目与中国的计算机程序设计竞赛(CSP-J),...

    RxJava 资源.zip

    强烈推荐扔物线的文章讲解非常详细NotRxJava懒人专用指南-这篇入门极力推荐,手把手,深入浅出教你实现一个简单的RxJava库,更好的理解RxJava的实现思路深入浅出RxJava(一基础篇)深入浅出RxJava (二操作符 ...

    深入浅出程序设计(中文版)

    《深入浅出程序设计(中文版)》介绍了编写计算机程序的核心概念:变量、判断、循环、函数与对象——无论运用哪种编程语言,都能在动态且多用途的python语言中使用具体示例和练习来运用并巩固这些概念。学习基本的工具...

    深入浅出设计模式 完整扫描版

    《深入浅出设计模式》总结了许多系统软件在设计开发过程中的难点,力图将设计模式的实际应用与实现原理有机结合起来,破解软件开发人员在学习设计模式过程不能透彻理解并灵活运用设计模式的难题。  所有章节都是先...

    深入浅出算法竞赛.pptx

    《深入浅出算法竞赛》是一本旨在帮助读者深入理解算法竞赛的书籍,通过简洁明了的语言和具体的实例,介绍了算法竞赛的核心知识点和常用算法,同时也强调了算法的实际应用和优化方法。该书籍可以帮助读者更好地理解和...

    免费电子书《深入浅出设计模式》PDF版.rar

    《深入浅出设计模式》这本书籍正是深入剖析了这些设计模式的精髓,为程序员们提供了一个详尽的学习资料。通过PDF版的免费电子书,无论是编程新手还是资深开发者都能从中获取宝贵的知识。 在《深入浅出设计模式》中...

    深入浅出程序设计 中文版

    《深入浅出程序设计》是一本面向初学者和进阶者的编程教材,旨在帮助读者全面理解编程基础,尤其是针对C#、ASP.NET以及MVC框架的运用。这本书以中文为载体,使得中国的开发者能更方便地掌握编程的核心概念和技术。 ...

    5G基础信令详解(深入浅出详细整理汇篇版).zip

    5G基础信令详解(深入浅出详细整理汇篇版).zip5G基础信令详解(深入浅出详细整理汇篇版).zip5G基础信令详解(深入浅出详细整理汇篇版).zip5G基础信令详解(深入浅出详细整理汇篇版).zip5G基础信令详解(深入浅出...

    深入浅出西门子WINCCV6.pdf

    《深入浅出西门子WinCC V6》是《深入浅出西门子自动化产品系列丛书》之一,系统地介绍了SIEMENS HMI/SCADA软件WinCC V6.0的主要功能及其组态方法,是学习WinCC V6.0的有益工具。本书分为基础篇和高级篇两大部分:...

    Android移动应用开发(第3版)卷1:基础篇

    总之,《Android移动应用开发(第3版)卷1:基础篇》是一本深入浅出的教程,覆盖了Android开发的方方面面,无论你是初涉Android开发还是寻求进阶,都能从中受益匪浅。通过阅读和实践书中的例子,你可以逐步建立起坚实...

    深入浅出MySQL数据库开发、优化与管理维护.doc

    MySQL 数据库开发、优化与管理维护 本文档旨在深入浅出 MySQL 数据库开发、优化与管理维护的...本文档旨在深入浅出 MySQL 数据库开发、优化与管理维护的知识点,为读者提供了 MySQL 数据库开发的基础知识和实践经验。

    西门子深入浅出WINCC V6(图书)2.rar

    西门子深入浅出WINCC V6(图书)2rar,西门子深入浅出WINCC V6(图书)2:本书是《深入浅出西门子自动化产品系列丛书》之一,系统地介绍了SIEMENS HMI/SCADA软件WinCC V6.0的主要功能及其组态方法,是学习WinCC V6.0的...

    深入浅出MySQL全文

    深入浅出MySQL全文 MySQL 是一种关系型数据库管理系统,广泛应用于各种行业和领域。本资源将从基础篇开始,详细讲解 MySQL 的安装、配置、启动和关闭服务、SQL 基础等知识点。 MySQL 的安装与配置 MySQL 的安装是...

    《深入浅出JavaScript》PDF版本下载.txt

    根据提供的文件信息,我们可以推断出这是一篇关于获取《深入浅出JavaScript》电子书的信息。下面我们将基于这个前提,围绕“深入浅出JavaScript”这一主题进行知识点的展开。 ### 深入浅出JavaScript概览 #### 一...

    深入浅出MFC-侯俊杰-学VC必读宝典一

    《深入浅出MFC》是侯俊杰先生撰写的一本关于Microsoft Foundation Classes (MFC) 的经典教程,尤其适合Visual C++(简称VC)开发者学习。MFC是微软为Windows平台开发应用程序提供的一种C++类库,它封装了Windows API...

    西门子深入浅出WINCC V6(图书)1.rar

    西门子深入浅出WINCC V6(图书)1rar,西门子深入浅出WINCC V6(图书)1: 本书是《深入浅出西门子自动化产品系列丛书》之一,系统地介绍了SIEMENS HMI/SCADA软件WinCC V6.0的主要功能及其组态方法,是学习WinCC V6.0的...

    JAVA程序员必读:基础篇.chm

    我整理生成的CHM格式文件 JAVA程序员必读:基础篇.chm 因为最近在搞这个所以整理了一些资料和大家分享 并非本人原创,郑重感谢原作者!

    android移动应用开发(第3版)卷Ⅰ:基础篇。正文扫描版

    《android移动应用开发(第3版)卷Ⅰ:基础篇》由Lauren Darcey、Shane Conder著,北京麦秆创智信息技术有限公司译,涵盖了android开发从概念、技术到市场推广应用的全部主题,内容包括android平台概览、android应用...

    信奥中的数学:基础篇(2023.07.20).pdf

    数学基础知识部分,教程以阶乘为例,深入浅出地介绍了这一在组合数学、概率论及算法中广泛应用的概念。阶乘的概念虽然简单,但其多样性足以让学生们在学习中发现数学的奥妙。教程提供了多种阶乘的介绍,包括0的阶乘...

Global site tag (gtag.js) - Google Analytics