RxJava
To use RXJAVA2 in Android, add the Gradle configuration first:
compile ‘io.reactivex.rxjava2:rxjava:2.0.1‘ compile ‘io.reactivex.rxjava2:rxandroid:2.0.1‘
Principle
Before you begin your study, let's introduce something of the original reason.
There are also many articles on the Internet that introduce Rxjava principles, usually these articles start with the Observer pattern, the observer, the Observer, the subscription relationship Balabala a lot of things, to tell the truth, when I first saw these articles have been around the time of these nouns have been dizzy, it took a long time to clarify the relationship between them. May be I am too stupid, the realm is not enough, understand not so many tall on the noun.
Today I use two water pipes instead of the observer and the observer, trying to explain their relationship in plain words, and here I will see the basic workings of Rxjava from the point of view of the event flow.
First assume there are two pipes:
Above a water pipe for the event of the water pipe, call it 上游
, the following water pipe for the event received the water pipe call it 下游
.
Two water pipes are connected in a certain way, so that each event is generated upstream, the event can be received downstream. Note here and the official website of the event diagram is the reverse, here the order of events sent is first 1, after 2, after 3 such order, the order of events received is also first 1, after 2, after 3 order, I think this is more in line with the thinking of our ordinary people, simple and clear.
Here upstream
and downstream
correspond to Observable
and Observer
in Rxjava, and the connection between them corresponds to subscribe ()
, so this relationship is represented by Rxjava:
Create an upstream observable:observable<integer> Observable = observable.create (New observableonsubscribe< Integer> () {@Override public void subscribe (observableemitter<integer> emitter) throws Exc eption {emitter.onnext (1); Emitter.onnext (2); Emitter.onnext (3); Emitter.oncomplete (); } }); Create a downstream Observer observer<integer> Observer = new observer<integer> () {@Override public void Onsubscribe (disposable d) {log.d (TAG, "subscribe"); } @Override public void OnNext (Integer value) {LOG.D (TAG, "" + value); } @Override public void OnError (Throwable e) {log.d (TAG, "error"); } @Override public void OnComplete () {LOG.D (TAG, "complete"); } }; Establish connection observable.subscribe (Observer);
The result of this operation is:
12-02 03:37:17.818 4166-4166/zlc.season.rxjava2demo D/TAG: subscribe12-02 03:37:17.819 4166-4166/zlc.season.rxjava2demo D/TAG: 112-02 03:37:17.819 4166-4166/zlc.season.rxjava2demo D/TAG: 212-02 03:37:17.819 4166-4166/zlc.season.rxjava2demo D/TAG: 312-02 03:37:17.819 4166-4166/zlc.season.rxjava2demo D/TAG: complete
Note: The upstream and downstream connections will not start sending events until the connection is established. That is, the method is called subscribe()
before the Send event begins.
Connecting this piece of code is a chain-like operation that Rxjava prides itself on:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { emitter.onNext(1); emitter.onNext(2); emitter.onNext(3); emitter.onComplete(); } }).subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "subscribe"); } @Override public void onNext(Integer value) { Log.d(TAG, "" + value); } @Override public void onError(Throwable e) { Log.d(TAG, "error"); } @Override public void onComplete() { Log.d(TAG, "complete"); } });
Next, explain the two unfamiliar gadgets: ObservableEmitter
and Disposable
.
Observableemitter:emitter is the meaning of the launcher, it is very good to guess, this is used to emit events, it can emit three types of events, by invoking the emitter onNext(T value)
, onComplete()
and onError(Throwable error)
can be issued next event, Complete event and Error event.
However, please note that it does not mean that you can randomly launch events and need to meet certain rules:
- An unlimited number of OnNext can be sent upstream, and an unlimited number of onnext can be received downstream.
- When a oncomplete is sent upstream, events after the upstream OnComplete are
继续
sent, and events are received after the OnComplete event is received downstream 不再继续
.
- When a onerror is sent upstream, events after the upstream onerror are
继续
sent, and events are received after the OnError event is received downstream 不再继续
.
- Upstream can not send oncomplete or onerror.
- The most critical is that OnComplete and onerror must be unique and mutually exclusive, that is, you cannot send multiple oncomplete, you cannot send multiple onerror, you cannot send a oncomplete first, and then you send a onerror, and vice versa.
Note: For OnComplete and onerror unique and mutually exclusive, it is necessary to control the code yourself, and if your code violates this rule in logic, it does not necessarily cause the program to crash. For example, sending multiple oncomplete can work properly, The first oncomplete is still received, but if you send more than one onerror, you receive a second onerror event that causes the program to crash.
Introduced Observableemitter, followed by the introduction of disposable, the word literal meaning is disposable supplies, used up can be discarded. So how to understand it in the Rxjava, corresponding to the example of the water pipe above, we can interpret it as an organ between two pipes, when it calls its dispose()
method, it will cut off two pipes, resulting in the downstream can not receive events.
Note: calling Dispose () does not cause upstream to no longer send events, and upstream continues to send the remaining events.
To take a look at an example, we let the upstream send 1,2,3,complete,4
in order, after receiving the second event downstream, cut off the water pipe, to see the results of the operation:
Observable.create (New observableonsubscribe<integer> () {@Override public void Subscri Be (observableemitter<integer> emitter) throws Exception {log.d (TAG, "Emit 1"); Emitter.onnext (1); LOG.D (TAG, "Emit 2"); Emitter.onnext (2); LOG.D (TAG, "Emit 3"); Emitter.onnext (3); LOG.D (TAG, "emit complete"); Emitter.oncomplete (); LOG.D (TAG, "Emit 4"); Emitter.onnext (4); }}). Subscribe (New observer<integer> () {private disposable mdisposable; private int i; @Override public void Onsubscribe (disposable d) {log.d (TAG, "subscribe"); mdisposable = D; } @Override public void OnNext (Integer value) {LOG.D (TAG, "OnNext:" + value); i++; if (i = = 2) {LOG.D (TAG, "Dispose"); Mdisposable.dispose (); LOG.D (TAG, "isdisposed:" + mdisposable.isdisposed ()); }} @Override public void OnError (Throwable e) {log.d (TAG, "error"); } @Override public void OnComplete () {LOG.D (TAG, "complete"); } });
The result of the operation is:
12-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: subscribe12-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: emit 112-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: onNext: 112-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: emit 212-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: onNext: 212-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: dispose12-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: isDisposed : true12-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: emit 312-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: emit complete12-02 06:54:07.728 7404-7404/zlc.season.rxjava2demo D/TAG: emit 4
From the running results we see that after receiving the OnNext 2 this event, cut off the water pipe, but upstream still sent 3, complete, 4 of these events, and upstream did not because sent OnComplete and stopped. You can also see that the downstream onSubscribe()
method is called first.
Disposable is more useful than this, after explaining the thread's dispatch, we will find its importance. With further in-depth explanation, we will find it in more places.
In addition, subscribe()
there are several overloaded methods:
public final Disposable subscribe() {} public final Disposable subscribe(Consumer<? super T> onNext) {} public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {} public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {} public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {} public final void subscribe(Observer<? super T> observer) {}
We've used the last one with Observer
parameters, and here are a few other ways to explain it.
- No indication of any of the
subscribe()
downstream not concerned about any event, you upstream in spite of sending your data to go, Lao Tzu no matter what you send.
- A method with one
Consumer
parameter indicates that the downstream only cares about the OnNext event, and the other events I pretended not to see, so if we only need the OnNext event we can write:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { Log.d(TAG, "emit 1"); emitter.onNext(1); Log.d(TAG, "emit 2"); emitter.onNext(2); Log.d(TAG, "emit 3"); emitter.onNext(3); Log.d(TAG, "emit complete"); emitter.onComplete(); Log.d(TAG, "emit 4"); emitter.onNext(4); } }).subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "onNext: " + integer); } });
Study and realization of Rxjava