如果您是Android开发人员,那么您可能已经听说过RxJava的好处,RxJava是ReactiveX库的一种流行的开源实现,它将反应式编程引入Java虚拟机(JVM)。
RxJava旨在减轻使用异步数据流的麻烦—尽管您将看到,RxJava对“数据”的定义非常广泛。 由于RxJava是JVM兼容的库,因此您可以在各种平台上使用它,但是在本系列中,我将向您展示如何使用RxJava 2进行Android开发。
在本系列文章的最后,您已经掌握了RxJava 2的所有要点,因此您可以开始创建可处理大量同步和异步数据的高反应性应用程序-所有这些代码都比通常使用的代码更简洁,更易于管理。仅靠Java就可以实现。
除了为RxJava新手提供介绍之外,如果您是RxJava 1的资深人士,并且希望向RxJava 2迈进,那么本系列文章将帮助您尽可能平稳地进行过渡。 虽然升级到库的最新版本听起来似乎并不重要,但是RxJava 2并不是您的典型更新,它是对RxJava的完全重写。 进行了如此多的更改后,很容易感到困惑,因此从新手的角度来看,花一些时间来熟悉RxJava 2可以从长远来看为您节省很多时间和沮丧。
在第一篇文章中,我将介绍RxJava是什么以及它为Android开发人员提供的主要好处。 我们还将深入研究任何 RxJava项目的核心组件: Observers
, Observables
和subscriptions。 在本教程结束时,您将创建一个简单的“ Hello World”风格的应用程序,其中包括所有这些核心组件。
RxJava的其他主要构建块是运算符,因此在第二部分中,我将探讨使用运算符来转换,组合,过滤和操作应用程序数据的不同方式。
在最后一部分中,我们将超越核心RxJava库,并看一看RxAndroid,它是一个完整的库,其中包含所有Android特定的扩展,您将需要释放Android的反应式编程的全部潜力。
我们有很多要讲的内容,所以让我们从要点开始:
无论如何,什么是RxJava?
RxJava是一个库,可让您以反应性编程风格创建应用程序。 反应式编程的核心是提供一种干净,有效的方式来处理和响应实时数据流,包括具有动态值的数据。
这些数据流不一定要采取传统的数据类型的形式,RxJava几乎一切对待数据,一切从变量特性,高速缓存流,像点击和划动,即使用户输入事件。
每个流发出的数据可以是值,错误或“完成”信号,尽管您不一定必须实现最后两个。 一旦创建了数据发射流,就将它们与消耗并作用于该数据的反应对象进行组合,根据流发出的内容执行不同的操作。 RxJava包括一堆有用的运算符来处理流 ,从而使执行过滤,映射,延迟,计数等操作变得容易。
为了创建数据流和对其进行响应的对象的工作流,RxJava扩展了Observer软件设计模式。 本质上,在RxJava中,您具有Observable
对象,这些对象发出数据流然后终止,而Observer
对象则订阅Observable
。 Observer
每次在其分配的Observable
发出值,错误或完成信号时都会收到通知。
因此,在一个非常高的层次上,RxJava的宗旨是:
- 创建一个
Observable
。 - 给
Observable
发出一些数据。 - 创建一个
Observer
。 - 将
Observer
分配给Observable
Observer
。 - 每当
Observer
任务从其分配的Observable
接收到发射时,就执行任务。
为什么选择RxJava?
学习任何新技术都需要时间和精力,作为一个面向数据的库,RxJava并不总是最容易掌握的API。
为了帮助您确定学习RxJava是否值得进行初始投资,让我们探究将RxJava库添加到Android项目中的一些主要好处。
更简洁,易读的代码
复杂,冗长且难以阅读的代码始终是坏消息。 凌乱的代码更容易出现错误和其他效率低下的问题,如果确实发生任何错误,那么如果您的代码很乱,那么您将很难追踪这些错误的来源。
即使您的项目确实没有任何错误地进行构建,复杂的代码仍然会困扰您-通常,当您决定在几个月后发布对应用程序的更新,启动项目并立即遇到麻烦时,纠结的代码!
RxJava允许您描述您想要实现的目标,而不是编写应用程序的操作说明列表,从而简化了处理数据和事件所需的代码。 RxJava还提供了一个标准的工作流,可用于处理应用程序中的所有数据和事件-创建一个Observable
,创建一个Observer
,将可Observer
分配给该观察者,冲洗并重复。 这种公式化的方法使代码非常简单易懂。
多线程变得容易
现代Android应用程序需要能够执行多任务。 至少,当您的应用程序在后台执行某些工作(例如管理网络连接,下载文件或播放音乐)时,您的用户将有望能够继续与应用程序的UI进行交互。 问题在于,默认情况下,Android是单线程的,因此,如果您的应用要成功执行多任务,则需要创建一些其他线程。
Android确实提供了开箱即用的多种方式来创建其他线程,例如服务和IntentServices
,但是这些解决方案都不是特别容易实现的,它们会很快导致复杂,冗长的代码,容易出错。
RxJava旨在通过提供特殊的调度程序和运算符来减轻创建多线程Android应用程序的痛苦。 这些使您可以轻松地指定应在其中执行工作的线程以及应在其中发布工作结果的线程。 RxJava 2.0默认包含许多调度程序,包括Schedulers.newThread
,它在创建新线程时特别有用。
要更改执行工作的线程,您只需要使用subscribeOn
运算符来更改观察者订阅可观察对象的位置。 例如,在这里我们创建一个新线程并指定应在该新线程上执行工作:
observable.subscribeOn(Schedulers.newThread())
Android上的多线程另一个长期存在的问题是,您只能从主线程更新应用程序的UI。 通常,每当需要将一些后台工作的结果发布到应用程序的UI时,都必须创建一个专用的Handler
。
再次,RxJava具有更直接的解决方案。 您可以使用observeOn
运算符指定一个Observable应该使用其他调度程序发送其通知,这实际上使您可以将Observable的数据发送到所选线程,包括主UI线程。
这意味着只需两行代码,您就可以创建一个新线程并将在该线程上执行的工作结果发送到Android的主UI线程:
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
好的,所以从技术上讲,我们在这里作弊,因为AndroidSchedulers.mainThread
仅作为RxAndroid库的一部分提供,我们将在第三部分中介绍。 但是,此示例确实使您了解了RxJava和RxAndroid简化以过于复杂而闻名的Android开发领域的能力。
灵活性更高
可观察对象以完全隐藏数据创建方式的方式发出数据。 由于观察者甚至看不到数据是如何创建的,因此您可以随意以任何方式实现Observable
。
一旦实现了Observable
,RxJava将提供范围广泛的运算符,可用于过滤,合并和转换这些Observable
发出的数据。 您甚至可以将越来越多的运算符链接在一起,直到您完全创建了应用程序所需的数据流。
例如,您可以合并来自多个流的数据,过滤新合并的流,然后将结果数据用作后续数据流的输入。 请记住,在RxJava中,几乎所有内容都被视为数据流,因此您甚至可以将这些运算符应用于非传统的“数据”,例如单击事件。
创建更多响应式应用
应用程序可以放心地加载内容页面,然后等待用户点击“ 下一步”按钮的日子已经一去不复返了。 如今,典型的移动应用需要能够对不断增长的各种事件和数据做出反应,最好是实时地做出反应。 例如,您的典型社交网络应用程序需要不断监听传入的喜欢,评论和朋友请求,同时在后台管理网络连接并在用户点击或滑动屏幕时立即做出响应。
RxJava库旨在能够同时实时地管理各种数据和事件,使其成为创建现代移动用户期望的那种高响应性应用程序的强大工具。
将RxJava添加到Android Studio
如果您确定RxJava确实可以为您提供Android开发实践的经验,那么成为RxJava大师的第一步就是将库添加到您的项目中。
使用您选择的设置创建一个新的Android Studio项目,然后打开模块级build.gradle文件,并将最新版本的io.reactivex.rxjava2:rxjava
为依赖项。
在撰写本文时,RxJava 2.0.5是最新版本,因此我的build.gradle文件如下所示:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
testCompile 'junit:junit:4.12'
compile 'io.reactivex.rxjava2:rxjava:2.0.5'
}
出现提示时,单击立即同步 。
接下来,打开MainActivity
文件并添加开始使用RxJava核心功能所需的导入:
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
如果您要从RxJava 1迁移,那么这些导入可能不是您所期望的,因为RxJava 1使用了完全不同的程序包名称(准确地说是rx
)。
但是,这不是任意更改名称:不同的程序包名称使您可以选择在同一项目中并排使用RxJava 1和RxJava 2。 如果您正在使用RxJava 1的项目中途进行,则可以添加RxJava 2库并立即开始使用更新的2功能,而不会破坏任何RxJava 1代码。
如果您从版本2开始RxJava之旅,那么请注意,如果您遇到任何使用rx
软件包名称的RxJava教程或代码,那么这就是RxJava 1代码,并且不太可能与版本2库兼容。
RxJava的构建基块
到目前为止,我们仅以非常高的水平介绍了RxJava。 现在该变得更加具体,并深入研究在RxJava工作中一次又一次地出现的两个最重要的组件: Observer
和Observable
。
到本节结束时,您不仅将对这两个核心组件有深入的了解,而且还将创建一个功能齐全的应用程序,该应用程序由发出数据的Observable
和对这些发出的辐射作出反应的Observer
。
创建一个Observable
一个Observable
类似于一个Iterable
在给定一个序列的情况下,它将迭代该序列并发出每个项目,尽管Observable
通常在Observer
订阅它们之前才开始发出数据。
每次Observable
发出一个项目时,它都会使用onNext()
方法通知其分配的Observer
。 一旦Observable
传输了所有值,它将通过调用以下任一方法终止:
-
onComplete
:如果操作成功,则调用。 -
onError
:如果引发Exception
则调用。
让我们来看一个例子。 在这里,我们创建可观察到的发射的数字1,2,3和4,然后终止。
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
//Use onNext to emit each item in the stream//
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onNext(4);
//Once the Observable has emitted all items in the sequence, call onComplete//
e.onComplete();
}
}
);
请注意,在此示例中,我正在准确说明正在发生的事情,所以不要让大量的代码使您失望! 这比实际在RxJava项目中创建Observable
用的代码要多得多。
创建一个观察者
Observer
是您使用subscribe()
运算符分配给Observable
对象。 Observer
订阅了Observable
,只要其Observer
发出以下任一事件,它将作出反应:
-
onNext
:Observable
已发出一个值。 -
onError
:发生错误。 -
onComplete
:Observable
已完成发出其所有值。
让我们创建一个订阅了我们的1,2,3,4 Observable
的Observer
。 为了使事情简单,此Observer
将通过向Android Studio的Logcat Monitor打印消息来响应onNext
, onError
和onComplete
:
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(Integer value) {
Log.e(TAG, "onNext: " + value);
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: All Done!");
}
};
//Create our subscription//
observable.subscribe(observer);
通过从Android Studio窗口(光标位于下面的屏幕快照中)的底部选择“ Android Monitor”选项卡,然后选择“ Logcat”选项卡,打开Android Studio的Logcat Monitor。
若要将此代码进行测试,请将您的物理Android设备连接到开发计算机,或者在兼容的AVD上运行您的项目。 一旦您的应用程序出现在屏幕上,您应该会看到Observable发出的数据。
用更少的代码创建一个可观察的对象
尽管我们的项目成功地发射了数据,但是我们使用的代码并不十分简洁,尤其是我们用来创建Observable
的代码。
幸运的是,RxJava提供了许多便利的方法,使您可以使用更少的代码来创建Observable
:
1. Observable.just()
您可以使用.just()
运算符将任何对象转换为Observable
。 结果Observable
将发出原始对象并完成。
例如,在这里我们正在创建一个Observable
,它将向所有Observers
发出一个字符串:
Observable<String> observable = Observable.just("Hello World!");
2. Observable.from()
.from()
运算符使您可以将对象集合转换为可观察的流。 您可以将阵列转换成Observable
使用Observable.fromArray
,一个Callable
成Observable
使用Observable.fromCallable
和Iterable
成一个Observable
使用Observable.fromIterable
。
3. Observable.range()
您可以使用.range()
运算符发出一系列连续整数。 您提供的第一个整数是初始值,第二个是您要发出的整数数。 例如:
Observable<Integer> observable = Observable.range(0, 5);
4. Observable.interval()
此运算符创建一个Observable
,它发射无限个递增整数序列,每次发射都由您选择的时间间隔分隔开。 例如:
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS)
5. Observable.empty()
empty()
运算符创建一个Observable
,该Observable
不会发射任何项目但会正常终止,这在您需要快速创建一个Observable
进行测试时非常有用。
Observable<String> observable = Observable.empty();
结论
在本文中,我们介绍了RxJava的基本构建块。
至此,您知道了如何创建和使用Observers
和Observables
以及如何创建订阅,以便Observables
可以开始发出数据。 我们还简要介绍了一些运算符,这些运算符使您可以使用更少的代码来创建一系列不同的Observables
。
但是,操作员不仅是减少所需编写代码量的便捷方法! 创建一个Observer
和Observable
很简单,但是操作员才是真正开始使用RxJava的可能的地方。
因此,在下一篇文章中,我们将探讨RxJava的一些最强大的运算符,包括最终可以使Android上的多线程无痛体验的运算符。 请继续学习RxJava库的真正功能。
可观察到的数据流程图来自ReactiveX文档,并已获得知识共享署名3.0许可的许可。
翻译自: https://code.tutsplus.com/tutorials/getting-started-with-rxjava-20-for-android--cms-28345