rxjava教程
In this tutorial, we’ll be introducing you to Reactive Programming and the library RxJava. We’ll be covering the basics of RxJava. How is it useful? What makes it so important for Android Development these days? It’s Anatomy. Everything will be discussed in this RxJava tutorial.
在本教程中,我们将向您介绍Reactive Programming和库RxJava 。 我们将介绍RxJava的基础知识。 有什么用? 如今,什么对Android开发如此重要? 这是解剖学。 一切将在此RxJava教程中讨论。
React式编程 (Reactive Programming)
- Reactive comes from the word react, which means to react to changes in the state instead of actually doing the state change. React性来自“React”一词,意思是对状态变化做出React,而不是实际进行状态变化。
- Reactive Programming is a programming paradigm that’s concerned with data streams and propagation of change. 响应式编程是一种与数据流和变更传播有关的编程范例。
- The reactive model listens to changes in the event and runs the relevant code accordingly. React式模型侦听事件中的更改,并相应地运行相关代码。
Assume the data streams are in the form of a river that flows continuously. Any observer/subscriber attached listening to the stream would receive the data. The data received can be further transformed using functions and this is where Functional Programming joins the already so powerful Reactive Programming.
假设数据流是连续流动的河流形式。 任何附加的侦听流的订阅者/订户都将接收数据。 可以使用函数对接收到的数据进行进一步转换,这是功能编程与已经如此强大的React式编程相结合的地方。
Together they are often called as Functional Reactive Programming.
它们在一起通常被称为功能响应式编程 。
In reactive programming, the flow is asynchronous thereby preventing any blocks on the main thread.
在React式编程中,流程是异步的,从而防止了主线程上的任何块。
How is it different from the Observer Pattern?
Observer Pattern does changes in the object based on certain triggers. Every Observer that’s dependent on the Subject gets notified when a change happens. What makes reactive programming different from this is the fact that reactive paradigm is based on the flow of data in the form of streams asynchronously.
与观察者模式有何不同?
观察者模式会根据某些触发器对对象进行更改。 发生更改时,将通知每个依赖于主题的 观察者 。 使得React式编程与此不同的是,React式范例基于异步形式的流形式的数据流。
为什么要进行Android的React式编程? (Why Reactive Programming for Android?)
Reactive Programming Paradigm and its library RxJava have gained huge popularity in the Android World.
Up until now, to do asynchronous tasks on Android we use the async tasks. That being said, it does have a lot of disadvantages and limitations.
响应式编程范例及其库RxJava在Android World中获得了巨大的普及。
到目前为止,要在Android上执行异步任务,我们将使用async任务 。 话虽如此,它确实有很多缺点和局限性。
Following are the things that Reactive Programming tries to make better:
以下是响应式编程试图使之变得更好的事情:
- Easier to chain multiple requests: There’s a problem in AsyncTask when you need to call multiple requests. It leads to bloated code. This is where Reactive code scores over the traditional async tasks. 轻松链接多个请求 :当您需要调用多个请求时,AsyncTask中存在问题。 它导致code肿的代码。 这是React式代码在传统异步任务上得分的地方。
- CallBack processing and tracking errors: With multiple requests in async tasks, background animations, it tends to get difficult to determine and track errors. Each asynchronous method call contains callback functions. Nest a few async methods and it’ll quickly lead to callback hell. Again, Reactive code tends to make this easier. 回调处理和跟踪错误 :由于异步任务中有多个请求,后台动画,因此往往难以确定和跟踪错误。 每个异步方法调用都包含回调函数。 嵌套一些异步方法,它将很快导致回调地狱。 同样,响应式代码往往使这一点变得更容易。
RxJava的 (RxJava)
- Rx stands for Reactive Extensions. Rx代表React式扩展。
- RxJava is a JVM implementation of Reactive Extensions. RxJava是Reactive Extensions的JVM实现。
- Reactive Extension is a library that’s used for writing asynchronous event-based reactive code by using observables. We’ll see what are observables shortly. Reactive Extension是一个库,用于使用可观察对象编写基于事件的异步响应式代码。 我们很快就会看到可观察的东西。
- RxJava is useful and very powerful in the sense that it takes care of multithreading very well. 在很好地处理多线程方面,RxJava非常有用且非常强大。
- If you’re a Java developer, you’ll be well aware of the fact that multithreading can get tricky. RxJava takes care of multi-threading by doing complex thread operations, keeping everything synchronized and returning the relevant things to the main thread. 如果您是Java开发人员,则将充分意识到多线程可能会变得棘手。 RxJava通过执行复杂的线程操作,保持所有内容同步并将相关内容返回到主线程来处理多线程。
- In Android, the main thread is the UI thread. RxJava handles multithreading with a level of abstraction. We need to write less code and the underlying methods do the rest for us. 在Android中,主线程是UI线程。 RxJava以抽象级别处理多线程。 我们需要编写更少的代码,而底层的方法将为我们完成其余的工作。
RxJava基础 (RxJava Basics)
The basic building blocks of RxJava are:
RxJava的基本构建块是:
- Observables: That emits data streams Observables :发出数据流
- Observers and Subscribers: That consume the data stream. The only difference between an Observer and a Subscriber is that a Subscriber class has the methods to unsubscribe/resubscribe independently without the need of the observerable methods. 观察者和订阅者 :消耗数据流。 观察者和订阅者之间的唯一区别是,订阅者类具有无需取消观察者即可独立地取消订阅/重新订阅的方法。
- Operators: That transform the data stream 运算符 :转换数据流
Before we get into the details of each of the above, let’s analyze each of them which an interesting analogy.
Let’s say the Observables is me the tutor, flowing the data.
You are the Observer/Subscriber who receives the data.
Additionally, Operators can transform the data that you receive from me. Example: An operator can change the default language of this tutorial data from English to any other language.
在详细介绍上述每一个内容之前,让我们分析一下每个有趣的类比。
假设Observables是我的导师,正在传递数据。
您是接收数据的观察者/订阅者。
此外,操作员可以转换您从我那里收到的数据。 示例:操作员可以将本教程数据的默认语言从英语更改为任何其他语言。
RxJava教程– IntelliJ中的项目设置 (RxJava Tutorial – Project Setup in IntelliJ)
Before we get down to the nitty-gritty details of RxJava and it’s implementation let’s create a new project in IntelliJ and add the RxJava dependency library in it.
在深入了解RxJava及其实现的细节之前,让我们在IntelliJ中创建一个新项目,并在其中添加RxJava依赖库。
Set the group and artifact id as shown below.
如下所示设置组和工件ID。
We need to add the following dependency to our build.gradle
of this project.
我们需要将以下依赖项添加到该项目的build.gradle
中。
compile 'io.reactivex:rxjava:1.1.0'
Now create a new Java class in the package. Your project structure should look like this:
现在,在包中创建一个新的Java类。 您的项目结构应如下所示:
RxJava观察者,观察者,订阅者 (RxJava Observables, Observers, Subscribers)
The role of an observable is to emit data. Let’s create a basic observable in our Java class.
可观察对象的作用是发出数据。 让我们在Java类中创建一个基本的Observable。
The Observable class can emit one or more sequence of streams using the method. It is meant to asynchronously push the items.
Observable类可以使用该方法发出一个或多个流序列。 它旨在异步推送项目。
This is in contrast to the Iterators interface which tends to pull items synchronously.
这与Iterators接口相反,后者倾向于同步提取项目。
Creating An Observable
创建一个可观察的
import rx.Observable;
import rx.Subscriber;
public class MyRxClass {
public static void main(String[] args) {
Observable<String> myObservable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
//Code to pass the data to the subscribers and observers goes here.
}
});
}
}
The create()
method is used to create a new Observable that can emit items. The call
method is where the items are pushed on an instance of the subscriber.
create()
方法用于创建可以发出项目的新Observable。 call
方法是将项目推送到订户实例上的位置。
创建观察者和订阅者 (Creating Observers and Subscribers)
Observers and Subscribers can be created in the following ways:
可以通过以下方式创建观察者和订阅者:
Subscriber<String> mySubscriber = new Subscriber<String>() {
@Override
public void onNext(String s) {
System.out.println(s);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
};
Observer<String> myObserver = new Observer<String>() {
@Override
public void onNext(String s) {
System.out.println("MyObserver onNext(): "+ s);
}
@Override
public void onCompleted() {
System.out.println("Observer complete");
}
@Override
public void onError(Throwable e) {
}
};
The onNext()
method gets the current value.
onNext()
方法获取当前值。
The onComplete()
method gets triggered when there is no more data left to be sent by the observable.
当可观察对象没有剩余要发送的数据时,将触发onComplete()
方法。
The onError()
method gets triggered in case an exception occurs.
如果发生异常,则会触发onError()
方法。
Note: Iterator does have the equivalents for onNext()
and onComplete()
(hasNext()
). It doesn’t have one when an exception is thrown. Another advantage of Reactive code.
注意 :迭代器确实具有onNext()
和onComplete()
( hasNext()
)的等效onNext()
。 引发异常时,它没有一个。 响应式代码的另一个优点。
将观察者,订户链接到可观察者 (Linking Observer, Subscribers to the Observable)
For the Observer and Subscriber to listen to the data stream emitted by the Observable they need to be subscribed using the subscribe()
method as shown below.
为了使Observer和Subscriber侦听Observable发出的数据流,它们需要使用subscribe()
方法进行订阅,如下所示。
myObservable.subscribe(mySubscriber);
myObservable.subscribe(myObserver);
The following code prints a Hello World String emitted by the observable.
以下代码打印可观察对象发出的Hello World字符串。
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
public class MyRxClass {
public static void main(String[] args) {
Observable<String> createObserver = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello World");
subscriber.onCompleted();
}
});
Subscriber<String> mySubscriber = new Subscriber<String>() {
@Override
public void onNext(String s) {
System.out.println("MySubscriber onNext(): "+ s);
}
@Override
public void onCompleted() {
System.out.println("Subscriber completed");
}
@Override
public void onError(Throwable e) {
System.out.println("OnError");
}
};
Observer<String> myObserver = new Observer<String>() {
@Override
public void onNext(String s) {
System.out.println("MyObserver onNext(): "+ s);
}
@Override
public void onCompleted() {
System.out.println("Observer completed");
}
@Override
public void onError(Throwable e) {
}
};
createObserver.subscribe(mySubscriber);
createObserver.subscribe(myObserver);
}
}
The following gets printed in the log console.
在日志控制台中打印以下内容。
MySubscriber onNext(): Hello World
Subscriber completed
MyObserver onNext(): Hello World
Observer completed
We can add more onNext()
statements in the call function. onNext()
/ onError()
statements after the onComplete()
statement won’t matter and will be skipped.
Try adding the following in the call()
method.
我们可以在调用函数中添加更多onNext()
语句。 onComplete()
onError()
语句之后的onNext()
/ onError()
语句无关紧要,将被跳过。
尝试在call()
方法中添加以下内容。
i=0;
while(i<5)
{
subscriber.onNext("Hello World "+ i);
i++;
}
Each of the items are emitted in onNext()
one by one.
每个项目都在onNext()
一个接一个地发出。
Observable.from() (Observable.from())
The create()
method is a bit verbose. Let’s look at what the from()
method does.
create()
方法有点冗长。 让我们看一下from()
方法的作用。
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import java.util.ArrayList;
import java.util.List;
public class MyRxClass {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
Observable<Integer> fromObservable = Observable.from(numbers);
Subscriber<Integer> intSubscriber = new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onNext(Integer integer) {
System.out.println("onNext: "+ integer);
}
};
fromObservable.subscribe(intSubscriber);
}
}
//Following is printed in the log console.
//onNext: 1
//onNext: 2
//onNext: 3
//onNext: 4
//onCompleted
The from()
method dissolves the list/array and emits each value one at a time.
from()
方法分解列表/数组,并一次发出一个值。
Observable.just() (Observable.just())
Observable.just()
emits whatever is present inside the just function. It can take between 2 to 9 parameters. If you pass a List/Array in just() it’ll emit the List/Array only.
Observable.just()
发出just函数中存在的任何内容。 它可以使用2到9个参数。 如果在just()中传递列表/数组,它将仅发出列表/数组。
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import java.util.ArrayList;
import java.util.List;
public class MyRxClass {
public static void main(String[] args) {
Subscriber<Integer> intSubscriber = new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onNext(Integer integer) {
System.out.println("onNext: "+ integer);
}
};
Observable<Integer> justObservable = Observable.just(4,4,6,null);
justObservable.subscribe(intSubscriber);
}
}
//Prints :
//onNext: 4
//onNext: 4
//onNext: 6
//onNext: null
//onCompleted
Observable.range() (Observable.range())
Observable.range(start,n)
is used to emit n
number of values starting from and inclusive of start
.
Observable.range(start,n)
用于发出n
个从start
的值(包括start
。
Observable<Integer> rangeObservable = Observable.range(2,5);
rangeObservable.subscribe(intSubscriber); //emits 2,3,4,5,6
Observable.empty()
creates an empty observable that emits nothing. It just completes.Observable.empty()
创建一个空的observable,不发出任何东西。 它就完成了。Observable.error()
creates an error. TheonError()
of all the subscribers would be called.Observable.error()
创建一个错误。 所有订户的onError()
都会被调用。Observable.never()
does nothing. Neither emits a complete nor an error.Observable.never()
不执行任何操作。 既不发出完整消息也不发出错误。
Observable.interval(),Observable.timer(),Observable.defer() (Observable.interval(), Observable.timer(), Observable.defer())
Observable.interval()
emits constant sequences of integers in ascending order which are evenly spaced by the interval specified.
Observable.interval()
会按升序发出恒定的整数序列,该序列按指定的间隔均匀地间隔开。
Observable intervalObservable = Observable.interval(1, TimeUnit.SECONDS);
intervalObservable.subscribe(System.out::println);
Thread.sleep(5000);
Emits 0 to 4 each second.
We’ve set the thread to sleep to prevent the main function from returning immediately.
每秒发出0到4。
我们将线程设置为Hibernate状态,以防止主函数立即返回。
Unlike interval, an Observable.timer()
emits value only after a certain time/delay.
It emits only a single value after the delay.
与interval不同, Observable.timer()
仅在特定时间/延迟后才发出值。
延迟后,它仅发出单个值。
Observable intervalObservable = Observable.timer(2, TimeUnit.SECONDS);
intervalObservable.subscribe(System.out::println);
Thread.sleep(5000);
//Prints
//0
The Observable.defer()
is similar to create()
except that it postpones the actual creation until an Observer subscribes.
Each subscription would recall the Observable creation. This ensures that the Observer would always receive the latest data.
Also, it ensures that no API calling occurs until Subscription. The data would be only fetched when required by the observer.
Observable.defer()
与create()
相似,除了它将实际创建推迟到Observer订阅之前。
每个订阅都将调用Observable创建。 这样可以确保观察者将始终接收最新数据。
而且,它确保在订阅之前不会发生API调用。 仅当观察者需要时才获取数据。
Observable<Integer> deferObservable = Observable.defer(() -> Observable.just(1, 2, 3));
经营者 (Operators)
An operator is used to transform the data emitted by the observable before it reaches the subscriber.
Both the observable and subscriber are independent of the transformations done by the Operator.
运算符用于转换可观察对象发出的数据,然后再到达订户。
可观察者和订户都独立于运营商进行的转换。
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.functions.Action1;
import rx.functions.Func1;
import java.util.ArrayList;
import java.util.List;
public class MyRxClass {
public static void main(String[] args) {
Observable.just(1,2,3)
.map(new Func1<Integer, Integer>() {
@Override
public Integer call(Integer i) {
return i*i;
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println(integer);
}
});
}
}
//Prints
1
4
9
In the above code, we’ve used the map function which calls the Func1
method callback in which we do our transformation.
在上面的代码中,我们使用了map函数,该函数调用Func1
方法回调,在其中进行转换。
The Action
callback is used to reduce the verbosity of the subscriber.
Action
回调用于减少订户的详细程度 。
Action1<T>
is equivalent toonNext()
whereT
is the type emitted.Action1<T>
等效于onNext()
,其中T
是发出的类型。Action0
is equivalent toonComplete()
Action0
等效于onComplete()
Action1<Throwable>
is equivalent toonError(Throwable)
Action1<Throwable>
等效于onError(Throwable)
The above code took care of onNext()
. We can take care of the others in the following way:
上面的代码处理了onNext()
。 我们可以通过以下方式照顾其他人:
Observable.just(1,2,3)
.map(new Func1<Integer, Integer>() {
@Override
public Integer call(Integer i) {
return i*i;
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println(integer);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
}
}, new Action0() {
@Override
public void call() {
System.out.println("Complete");
}
});
//or
Action0 actionComplete = new Action0() {
@Override
public void call() {
System.out.println("Complete");
}
};
Action1<Throwable> actionError = new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
}
};
Action1<Integer> actionNext = new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println(integer);
}
};
Observable.just(1,2,3)
.map(new Func1<Integer, Integer>() {
@Override
public Integer call(Integer i) {
return i*i;
}
})
.subscribe(actionNext,actionError , actionComplete);
Let’s unleash lambda expressions to reduce the verbosity even further.
让我们释放lambda表达式以进一步降低冗长程度。
Observable.just(1,2,3)
.map(i -> i*i)
.subscribe(System.out::println);
Wow. That’s so concise.
The Observable emits values which are squared by the Operators and the transformed values are printed.
哇。 简明扼要。
Observable发出由操作员平方的值,并打印转换后的值。
Observable.just(1,2,3)
.map(i -> i*i)
.map(i -> i*i)
.subscribe(System.out::println);
//prints
1
16
81
Let’s look at another operator. Namely filter()
which is used to filter the values based on certain conditions.
让我们看看另一个运算符。 即filter()
,用于根据某些条件过滤值。
Observable.just(1,2,3)
.map(i -> i*i)
.map(i -> i*i)
.filter(i -> i>10)
.subscribe(System.out::println);
//Prints
16
81
This brings an end to the RxJava tutorial. You can download the sample code from the link below.
RxJava教程到此结束。 您可以从下面的链接下载示例代码。
rxjava教程