一起读RxJava源码(一)——简介

  RxJava已经火了一段时间了,我的项目包括我最近看的很多项目都在用RxJava。之前学习了一些RxJava原理及源码,有了一些感悟,在此做一个系列进行总结。
  学无止境,大家加油!

版权声明:本文为博主原创文章,未经博主允许不得转载。

读前注意事项:
1.本篇文章创作时间为2017.5.2,由于之前没有个人博客,所以现在才发出来。在发出之前做了些许修改。
2.本编文章基于RxJava 1.x。
3.由于本人是个Android搬砖工,因此本文仅限于Android上对RxJava的理解和运用,其他类型的工友能看懂主要思想和逻辑即可。
4.推荐几篇文章:

5.本系列文章主要侧重于RxJava基本原理和基本实现的源码解析,对RxJava各种操作符的各种用法可能不会介绍得很全,算是一篇RxJava源码解读入门级的文章。 RxJava其他各种炫酷的用法可以去拜读上面几位大神的文章,写的都很详细。如果还想更深入学习推荐阅读官方文档。

一起读RxJava源码系列:
一起读RxJava源码(一)——简介
一起读RxJava源码(二)——基础知识:观察者模式
一起读RxJava源码(三)——RxJava的基本实现
一起读RxJava源码(四)——转换操作符
一起读RxJava源码(五)——线程调度
一起读RxJava源码(六)——深入浅出:基于波浪事件流和模块化的思路分析RxJava

1. 前言

  RxJava应该是从大概15年开始(?大概吧),被越来越多的开发者关注并学习。至今已然成为很多公司和个人项目的首选,尤其是没有自己网络封装库的公司的首选(emmm…)。比较著名的就是各种博客论坛公众号都在介绍的RxJava+Retrofit+mvp

  虽然目前RxJava 2.x已经出了一段时间了,官方也已经终止对RxJava 1.x的维护。但是我还是没有远见的写了一篇关于RxJava 1.x的文章。主要是因为在自己看源码的那个时间段里RxJava 1.x的文章最多,而RxJava 2.x的文章没有找到通俗易懂适合初学者的。因此本着初学源码,理解为上的原则,还是选择学习RxJava 1.x的源码来学习。当然,不出意外的,首先主要看了最经典的装X必读:朱凯(扔物线)写的《给 Android 开发者的 RxJava 详解》。看了N遍之后,得出了下面的结论:

  后来又拜读了张磊大神写的RxJava系列1~7,在掉了几万根秀发以后终于摸到了一些门道——大概就是我的头型还不够圆……以及RxJava源码的一些理解。于是写下了这篇文章,跟着学渣装X慢慢看懂RxJava。

2. RxJava相关概念

2.1 先忽略Java,来看下Rx

  RX,全称是ReactiveX,官网链接在上面的推荐文章里。官网上的第一句话就明确的写出了它的作用:

An API for asynchronous programming with observable streams

大概翻译:一种异步编程API,使用(with介词,我觉得翻译成使用比较好)可观察流

Rx的官方定义

这个定义有点抽象,但是也告诉了我们三个事情。
1、这是一个API
2、这是一个用来实现异步编程功能的API
3、实现这个功能使用的是可观察流的方式

下面再来看官网的第二句话和图:

The Observer pattern done right
ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming

大概翻译:
观察者模式的正确使用
ReactiveX是从观察者模式、迭代器模式和函数式编程的最佳思想的组合。

Rx定义的官方解释

  所以,上面的可观察流可以理解为是一种观察者模式、迭代器模式和函数式编程的组合。当然起主要作用的我认为是观察者模式,毕竟done right

  再来看官网的最下面一句话:

ReactiveX is more than an API, it’s an idea and a breakthrough in programming. It has inspired several other APIs, frameworks, and even programming languages.

大概翻译:ReactiveX不仅仅是一个API,它是编程的一个思想和突破。它启发了其他几个API、框架,甚至是编程语言。

Rx的意义

  瞬间高大上了有木有,把ReactiveX升华成了一种思想。思想能干什么?思想能改变世界啊……扯远了,所以这么牛X的框架,就问你:

  那我们开始吧。

2.2 所以RxJava是什么

  刚刚介绍了Rx,后面加上Java当然就是使用Java语言来编写和使用的Rx。官网上还有其他语言的Rx。比如:RxJS、Rx.NET、RxScala、RxSwift……。本系列的所有文章都是基于RxJava来讲解的。

  对于Rxjava是什么。大神们给的一个词是“异步”。

“RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.”

大概翻译:RxJava 是Reactive Extensions在 Java VM 上的实现, 是一个用可观测序列(基于观察者模式)来组成异步的、基于事件的程序的库。
注:Reactive Extensions:An API for asynchronous programming with observable streams。(Reactive Extensions是用可观测流实现异步编程的API,有基于各种语言的库。RxJava是其中一种。)

“It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.”
大概翻译:它扩展了观察者模式以支持数据/事件序列,并添加了操作符允许您声明性地将序列组合在一起,同时抽象出对诸如低级线程、同步、线程安全和并发数据结构等。

RxJava在GitHub主页上的自我介绍

  简单理解:异步操作库。这个库基于异步可以实现诸多功能,其中最火的莫过于响应式编程,在后面的章节里会稍微介绍一下响应式编程相关基础。

3. RxJava好在哪

  好在哪主要是得和别的类库比较。Android一般是和本平台上已经为开发者提供的AsyncTask,Handler等用来做异步操作的类库比较。比较的结果就是:简洁随着程序逻辑变得越来越复杂,它依然能够保持简洁

注:以下例子均取自大神朱凯(扔物线)的《给 Android 开发者的 RxJava 详解》一文(不包含表情包),例子确实很通俗易懂,所以本人就不胡编乱造了。直接看。

  假设有这样一个需求:界面上有一个自定义的视图imageCollectorView,它的作用是显示多张图片,并能使用addImage(Bitmap)方法来任意增加显示的图片。现在需要程序将一个给出的目录数组File[] folders中每个目录下的 png 图片都加载出来并显示在imageCollectorView中。需要注意的是,由于读取图片的这一过程较为耗时,需要放在后台执行,而图片的显示则必须在UI线程执行。常用的实现方式有多种,这里贴出其中一种:

通过Thread新建线程读取图片,并通过runOnUiThread更新imageCollectorView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
new Thread() {
@Override
public void run() {
super.run();
for (File folder : folders) {
File[] files = folder.listFiles();
for (File file : files) {
if (file.getName().endsWith(".png")) {
final Bitmap bitmap = getBitmapFromFile(file);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
imageCollectorView.addImage(bitmap);
}
});
}
}
}
}
}.start();

  而如果使用 RxJava ,实现方式是这样的:

RxJava实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Observable.from(folders)
.flatMap(new Func1<File, Observable<File>>() {
@Override
public Observable<File> call(File file) {
return Observable.from(file.listFiles());
}
})
.filter(new Func1<File, Boolean>() {
@Override
public Boolean call(File file) {
return file.getName().endsWith(".png");
}
})
.map(new Func1<File, Bitmap>() {
@Override
public Bitmap call(File file) {
return getBitmapFromFile(file);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) {
imageCollectorView.addImage(bitmap);
}
});

  这里代码看上去行数是变多了,但是逻辑却变得简洁了,用有文化(装X)一点的词形容叫“对仗”。RxJava 实现的是一条从上到下的链式调用,没有任何嵌套。
  配合Lambda表达式使用效果拔群:

RxJava+Lambda
1
2
3
4
5
6
7
Observable.from(folders)
.flatMap((Func1) (folder) -> { Observable.from(file.listFiles()) })
.filter((Func1) (file) -> { file.getName().endsWith(".png") })
.map((Func1) (file) -> { getBitmapFromFile(file) })
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe((Action1) (bitmap) -> { imageCollectorView.addImage(bitmap) });

  所以, RxJava 好在哪?就好在简洁,好在那把什么复杂逻辑都能穿成一条线的简洁。

4. 总结

  Rxjava简介到这就差不多了,相信大家都了解了Rx的作用和功能,也能感受到RxJava的优势——简洁。在进入正题之前,还有一些基础要熟悉一下。下一篇文章会对基础之一的观察者模式做一个介绍,敬请关注!

Powered by Hexo and Hexo-theme-hiker

Copyright © 2018 - 2023 TEN-Z'S BLOG All Rights Reserved.

访客数 : | 访问量 :