For more information about RxJava in observer mode, see rxjava for more information.

Source: Internet
Author: User

For more information about RxJava in observer mode, see rxjava for more information.
Preface what is RxJava

RxJava-Reactive Extensions for the JVM-a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

The above is the introduction of RxJava on Github, which roughly means,For the responsive extension Implementation of JVM (Java Virtual Machine), a library that uses an observed sequence on Java VM to Implement Asynchronous and event-based programming is combined.

RxJava should have been used by many users, so I will not talk about it here. We all know that RxJava isObserver ModeThe following describes the implementation logic of RxJava2 Based on the implementation mechanism of the observer mode. Only by truly understanding the implementation principles of RxJava can we locate problems more quickly and accurately when encountering problems.

This source code analysis is based on RxJava Release 2.1.7

Observer Mode

Here we will briefly review the composition and usage of the observer mode. Through the analysis in the previous article on the observer mode, we know that the observer mode has four important roles:

Abstract topic: Define the function of adding and deleting an observer, that is, the function of registering and unregistering.Abstract observer: Define what the observer will do after receiving the topic notificationSubject: Abstract theme implementationSpecific observer: Implementation of abstract observer

When we have created a specific topic and observer class, we can use the observer mode. Below is a simple test demo.

Public class TestObservePattern {public static void main (String [] args) {// create a topic (observed) ConcreteSubject concreteSubject = new ConcreteSubject (); // create the observer ObserverOne observerOne = new ObserverOne (); // Add the observer concreteSubject for the topic. addObserver (observerOne); // The topic notifies all observers of concreteSubject. notifyAllObserver ("wake up, wake up ");}}

The preceding figure shows how to use the observer mode. Now let's take a look at how RxJava uses the observer mode with the following questions.

After using RxJava for so long, you can think about the following issues:

How are the four important roles mentioned above defined in RxJava? In RxJava, how is the specific observer instantiated? In RxJava, how does one subscribe to the observer and topic? In RxJava, how does the upstream send events and how does the downstream receive events? What are the benefits of adjusting the regular observer mode in RxJava?

If you have a clear answer to the above questions, congratulations, you don't need to read the following content, O (∩ _ ∩) O Haha ~.

Many developers may learn RxJava fromUpstreamAndDownstreamIn the beginning, we can consider that such a description is more focused on the features of RxJava event sequences. FromObserved (subject)AndObserverFrom the perspective of the RxJava observer pattern. The topic here is upstream, and the observer is downstream. No matter which angle you want to understand, the source code is just like this. It doesn't matter whether you are right or wrong. It's just that everyone's cognitive angle is different. Just select a method that you can better understand.

Well, if you see this, it means you have some questions about the above issues, so let's take a look at the source code implementation of RxJava from these issues.

Implementation of the observer mode of RxJava2

Let's take a look at what RxJava is like with the above questions. To facilitate narration and memory, Let's first look at the most basic usage of RxJava2.

private void basicRxjava2() {        Observable mObservable = Observable.create(new ObservableOnSubscribe() {            @Override            public void subscribe(ObservableEmitter e) throws Exception {                e.onNext("1");                e.onNext("2");                e.onNext("3");                e.onNext("4");                e.onComplete();            }        });        Observer mObserver = new Observer() {            @Override            public void onSubscribe(Disposable d) {                Log.e(TAG, "onSubscribe: d=" + d);                sb.append("\nonSubcribe: d=" + d);            }            @Override            public void onNext(Object s) {                Log.e(TAG, "onNext: " + s);                sb.append("\nonNext: " + s);            }            @Override            public void onError(Throwable e) {                Log.e(TAG, "onError: " + e);                sb.append("\nonError: " + e.toString());                logContent.setText(sb.toString());            }            @Override            public void onComplete() {                Log.e(TAG, "onComplete");                sb.append("\nonComplete: ");                logContent.setText(sb.toString());            }        };        mObservable.subscribe(mObserver);    }

The above code should be easy to understand, and you can come up with the output with your eyes closed. Based on this code, we will analyze RxJava in turn based on the problems mentioned above.

Four important role abstraction topics

First, you can look at this Observable class.

public abstract class Observable
 
   implements ObservableSource
  
    {……}
  
 

He implemented the ObservableSource interface and then looked at the ObservableSource

public interface ObservableSource
 
   {    /**     * Subscribes the given Observer to this ObservableSource instance.     * @param observer the Observer, not null     * @throws NullPointerException if {@code observer} is null     */    void subscribe(@NonNull Observer
   observer);}
 

Obviously, ObservableSource is the role of the abstract topic (observer. The subscribe method is used to subscribe to the Observer (Observer) role according to the responsibilities agreed in the previous Observer mode. Here we can also see that the role of the abstract Observer is the Observer.

Here, you may have questions. Is this simple? Does abstract topic (upstream) need to send events? Where does onNext (), onComplete (), and onError () go? Don't worry. Let's take a look at it later.

Subject

Looking back, we can continue to look at Observable. It implements the ObservableSource interface and its subscribe method, but it is not actually completed.TopicAndObserverInstead, it transfers this function to another abstract method subscribeActual (which will be analyzed later ).

Therefore, Observable is still an abstract class. We know thatAbstract classes cannot be instantiated.Therefore, theoretically, it seems that he cannot be a role of a specific topic. In fact, the Observable provides a series of internal functions such as create, defer, fromXXX, repeat, and just.Create OperatorUsed to create various Observable.

    public static 
 
   Observable
  
    create(ObservableOnSubscribe
   
     source) {        ObjectHelper.requireNonNull(source, "source is null");        return RxJavaPlugins.onAssembly(new ObservableCreate
    
     (source));    }
    
   
  
 

There are many child classes in RxJava.

Indeed, you can think that these subclasses are actually specific theme. However, from another angle, we can regard Observable as a proxy class. on the client side, you only need to call the create method and what kind
The Observable can tell me the difference. You don't have to worry about the difference between different Observeable. package it on me and ensure that you will return the desired Observeable instance to you.

At the same time, another huge contribution of Observable is to define many operators. We usually use map, flatMap, and distinct, which are also defined here. And these methods are of the final type, so all its subclasses will inherit and cannot change the implementation of these operators.

Therefore, Observable is a specific topic.

Abstract observer

As mentioned in the abstract topic, the Observer is the role of the abstract Observer.

public interface Observer
 
   {    void onSubscribe(@NonNull Disposable d);    void onNext(@NonNull T t);    void onError(@NonNull Throwable e);    void onComplete();}
 

It is very consistent with the abstract responsibilities of the Observer in the Observer mode. The Observer defines what the Observer should do after receiving the topic (upstream) notification. OnSubscribe is also defined here.

Specific observer

For this specific observer, o (operator □lead) oo (operator □lead) o. We usually use a new Observer instance. RxJava has many Observer subclasses. If you are interested, please take a look at them. An interesting question can be raised here. It is also an abstract class. Why can an interface be directly instantiated, but a class modified with abstract cannot?

How the specific observer is instantiated

Let's take a look at this Code:

Observable mObservable = Observable. create (new ObservableOnSubscribe () {@ Override public void subscribe (ObservableEmitter e) throws Exception {}}); public static
 
  
Observable
  
   
Create (ObservableOnSubscribe
   
    
Source) {ObjectHelper. requireNonNull (source, "source is null"); return RxJavaPlugins. onAssembly (new ObservableCreate
    
     
(Source);} public static
     
      
Observable
      
        OnAssembly (@ NonNull Observable
       
         Source) {Function
        F = onObservableAssembly; // whether other operator operations exist. if yes, execute the if (f! = Null) {return apply (f, source);} return source ;}
       
      
     
    
   
  
 

In RxJava code, there are often empty checks such as ObjectHelper. requireNonNull to prevent NPE from appearing to the maximum extent..

When we use the create operator to create an Observable, we seem to have gone through many methods,Without considering any other operatorsThe whole process is simplified.

  Observable mObservable=new ObservableCreate(new ObservableOnSubscribe())

From the previous analysis, we can also see that ObservableCreate is a subclass of the Observeable abstract class. Let's take a brief look at his implementation.

public final class ObservableCreate
 
   extends Observable
  
    {    final ObservableOnSubscribe
   
     source;    public ObservableCreate(ObservableOnSubscribe
    
      source) {        this.source = source;    }    @Override    protected void subscribeActual(Observer
      observer) {        ……    }}
    
   
  
 

As you can see, his only constructor requires an ObservableOnSubscribe instance, And he implements the subscribeActual method, which indicates that he actually handlesTopicAndObserverTo implement the subscription logic.

After reading for a long time, you may have been curious. What is ObservableOnSubscribe? He is actually very simple.

/** * A functional interface that has a {@code subscribe()} method that receives * an instance of an {@link ObservableEmitter} instance that allows pushing * events in a cancellation-safe manner. * * @param 
 
   the value type pushed */public interface ObservableOnSubscribe
  
    {    /**     * Called for each Observer that subscribes.     * @param e the safe emitter instance, never null     * @throws Exception on error     */    void subscribe(@NonNull ObservableEmitter
   
     e) throws Exception;}
   
  
 

ε = ('commandid *) alas, why is another subscribe? What is this? Don't worry. read comments. This means that after the subscribe receives an ObservableEmitter instance, it will allow the subscribe to send events in a form that can be safely canceled (that is, canceled.

That is to say, there will be an object. If you give him an ObservableEmitte instance, he will not take the initiative to send the event before giving it to him, and he will be holding it all the time.So far, Do you think of anything? In RxJava, we know that only the observer (downstream) subscribes to the topic (upstream) and the topic will send events. This is one of the differences from the normal observer mode.

Now let's take a look at the mysterious ObservableEmitter?

public interface ObservableEmitter
 
   extends Emitter
  
    {    void setDisposable(@Nullable Disposable d);    void setCancellable(@Nullable Cancellable c);    boolean isDisposed();    ObservableEmitter
   
     serialize();      /**     * Attempts to emit the specified {@code Throwable} error if the downstream     * hasn't cancelled the sequence or is otherwise terminated, returning false     * if the emission is not allowed to happen due to lifecycle restrictions.     *
    

* Unlike {@link #onError(Throwable)}, the {@code RxJavaPlugins.onError} is not called * if the error could not be delivered. * @param t the throwable error to signal if possible * @return true if successful, false if the downstream is not able to accept further * events * @since 2.1.1 - experimental */ boolean tryOnError(@NonNull Throwable t);}

Here we can take a look at the tryOnError method. We can see that it will pass some types of errors to the downstream.

O (zookeeper) o is an interface and inherits another interface. What is the situation? Continue watching

public interface Emitter
 
   {    void onNext(@NonNull T value);    void onError(@NonNull Throwable error);    void onComplete();}
 

Surprise, no surprise? Haha, I finally found you. The familiar onNext, onError, and onComplete are here.

There is a problem here to think about. In the abstract observer, four methods are defined to process events. Here there are only three methods. According to the corresponding relationship, there seems to be a lack of onSubscribe, what is the problem? There will be analysis later. You can think about it first.

The meanings of these two interfaces are obvious. To sum up:

Emitter defines three mechanisms for sending events. ObservableEmitter extends Emitter and adds Disposable-related methods to cancel event sending.

Well, after a large circle, it is for a line of code:

  Observable mObservable=new ObservableCreate(new ObservableOnSubscribe())

Summarize what the specific topic (upstream) has done:

The ObservableOnSubscribe object reference ObservableOnSubscribe is an interface that creates an ObservableCreate Instance Object ObservableCreate and uses its ObservableEmitter instance to send events after the subscribe method is called. ObservableEmitter inherits from Emitte. How to subscribe, send events, and receive events

In order to facilitate the description, we have connected question 3 and question 4.

Through the above description, the specific topic and the specific observer have been created, and the next step is to implement the subscription relationship between the two.

mObservable.subscribe(mObserver);

It should be clear that the Observer (downstream) subscribes to the topic (upstream), although it seems from the code that the former has subscribed to the latter, do not confuse it.

Let's take a look at the Observable subscribe () method:

    public final void subscribe(Observer
  observer) {        ObjectHelper.requireNonNull(observer, "observer is null");        try {            observer = RxJavaPlugins.onSubscribe(this, observer);            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");            subscribeActual(observer);        } catch (NullPointerException e) { // NOPMD            throw e;        } catch (Throwable e) {         ……        }    }

As mentioned above, Observable does not actually implement subscribe, but transfers it to the subscribeActual () method.

As mentioned above, the Observable instance is an ObservableCreate object, so we will go to this class to see the implementation of subscribeActual.

// For convenience, take a look at the constructor public ObservableCreate (ObservableOnSubscribe
 
  
Source) {this. source = source;} @ Override protected void subscribeActual (Observer
  Observer) {CreateEmitter
  
   
Parent = new CreateEmitter
   
    
(Observer); observer. onSubscribe (parent); try {source. subscribe (parent);} catch (Throwable ex) {Exceptions. throwIfFatal (ex); parent. onError (ex );}}
   
  
 

CreateEmitter implements the previously mentioned ObservableEmitter interface. Here is a key code:

observer.onSubscribe(parent);

When we saw the definition of Emitter, we said that the onSubscribe method is missing and we will understand it here.OnSubscribe is not an event actively sent by the topic (upstream), but an event called by the observer (downstream). It is only used to obtain the Emitter instance object, to be accurate, it should be the Disposable instance object, so that the downstream can control the upstream.

The next step is simpler. The source is ObservableOnSubscribe. According to the previous logic, call its subscribe method and give it an ObservableEmitter object instance. The ObservableEmitter starts to send event sequences. In this way, once the subscription is started, the topic (upstream) starts to send events.

Next, let's look at the implementation of CreateEmitter.

public final class ObservableCreate
 
   extends Observable
  
    {    final ObservableOnSubscribe
   
     source;    public ObservableCreate(ObservableOnSubscribe
    
      source) {        this.source = source;    }    @Override    protected void subscribeActual(Observer
      observer) {        CreateEmitter
     
       parent = new CreateEmitter
      
       (observer); observer.onSubscribe(parent); …… } static final class CreateEmitter
       
         extends AtomicReference
        
          implements ObservableEmitter
         
          , Disposable { private static final long serialVersionUID = -3434801548987643227L; final Observer
           observer; CreateEmitter(Observer
           observer) { this.observer = observer; } @Override public void onNext(T t) { if (t == null) { onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); return; } if (!isDisposed()) { observer.onNext(t); } } @Override public void onError(Throwable t) { if (!tryOnError(t)) { RxJavaPlugins.onError(t); } } @Override public boolean tryOnError(Throwable t) { if (t == null) { t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); } if (!isDisposed()) { try { observer.onError(t); } finally { dispose(); } return true; } return false; } @Override public void onComplete() { if (!isDisposed()) { try { observer.onComplete(); } finally { dispose(); } } } @Override public void setDisposable(Disposable d) { DisposableHelper.set(this, d); } @Override public void setCancellable(Cancellable c) { setDisposable(new CancellableDisposable(c)); } @Override public ObservableEmitter
          
            serialize() { return new SerializedEmitter
           
            (this); } @Override public void dispose() { DisposableHelper.dispose(this); } @Override public boolean isDisposed() { return DisposableHelper.isDisposed(get()); } }}
           
          
         
        
       
      
     
    
   
  
 
His constructor needs an observer instance; he implements the ObservableEmitter interface and implements his three methods in turn;
In each onNext event, it no longer accepts the type of null parameter. When the event sequence is not interrupted, the topic (upstream) the event T is passed to the observer (downstream ). When an onComplete event occurs, it also notifies the downstream. If an exception occurs, when the onError event sequence is interrupted, it is not directly transmitted to the downstream, instead, some specific types of errors are passed to the downstream when the tryOnError event is processed internally. It implements the Disposable interface. Based on the acquired Emitter instance object, the downstream can easily obtain the event sequence information, or even automatically close the event sequence, and disconnect the subscription relationship between the topic and the observer in the Observer mode. What are the benefits of adjusting the regular observer mode in RxJava?

Finally, let's briefly explain how the regular observer mode is adjusted in RxJava and what is worth learning from. Most of the advantages have been mentioned above. Here we will summarize them.

After the Observer subscribes to a topic, the topic starts to send the event. In RxJava, the Observer obtains the Disposable object in the sending event through onSubscribe, so that the Observer can actively obtain the status of the two objects in the subscription relationship, even control or interrupt Event Sequence sending. In the regular observer mode, a topic has the right to add a subscriber, but it can also be used to remove a specific subscriber, because only the topic that holds all subscriber sets abstract the topic (upstream) the onNext, onComplete, and onError events are not directly controlled, but only the sending of Emitter instances is concerned. The ObservableOnSubscribe interface monitors the sending of ObservableEmitter objects, once this object is accepted, it will start to send specific events through it, which can be a bit of an observer mode nested meaning.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.