Rxjava Analysis-subject

Source: Internet
Author: User

Subject in Reactivex is as a bridge or proxy for observer and observerable. Because it is an observer, it can subscribe to one or more observable objects, and since he is an observable, it can pass and release the data objects it observes, and can release new objects.

1. Types of subject

There are four types of subject designed for different purposes, namely Asyncsubject, Behaviorsubject, Publishsubject and Replaysubject.

1.1 Asyncsubject

Asyncsubject only releases the last data released by observable, and only after observable is complete. However, if observable is terminated because of an exception, Asyncsubject will not release any data, but will pass an exception notification to observer.

1.2 Behaviorsubject

When observer subscribes to a behaviorsubject, it releases the recently released data object from the observable, which is a default value when no data is released. Next, all the data released by observable is released. If observable is terminated abnormally, Behaviorsubject will not release data to subsequent observer, but will pass an exception notification to observer.

1.3 Publishsubject

Publishsubject only releases data released after the subscription observable to observer.

1.4 Replaysubject

Regardless of when observer subscribes to Replaysubject,replaysubject, it releases observable freed data to all observer.
There are different types of replaysubject, which are used to limit the range of replay, such as setting the specific size of the buffer, or setting a specific time range.
If you use REPLAYSUBJECT as observer, be careful not to call the OnNext, OnComplete, and OnError methods in multiple threads, because this can lead to a sequence of confusion, which violates the observer rule.

2. Rxjava's subject source analysis2.1 Subject

Subject represents an object that is both observable and observer. The Code for class subject is as follows:

Package Rx.subjects;import Rx. Observable;import Rx. Observer;import Rx. subscriber;/** * Represents an object it is both a Observable and an Observer. * * Public Abstract  class Subject<T, R> extends Observable<R > implements Observer<T> {    protectedSubject (onsubscribe<r> onsubscribe) {Super(Onsubscribe); } Public Abstract BooleanHasobservers (); Public FinalSerializedsubject<t, r> toserialized () {return NewSerializedsubject<t, R> ( This); }}
2.2 Behaviorsubject

Subject has four primary subclasses, Asyncsubject, Behaviorsubject, Publishsubject, and Replaysubject, respectively. Next, we will take behaviorsubject as an example for source code analysis.

2.2.1 Behaviorsubject Subscription Subscribe process

When you need to use subject, call subject's subscribe (..) Method, the method actually calls the following subscribe (SUBSCRIBER<? Super T> Subscriber) method, so the other subscribe methods convert the input parameters into a Subscriber object.

Public final Subscription subscribe (subscriber<? superT> Subscriber) {...New Subscriber so onStart it Subscriber.onstart ();...The code below is exactly the same an unsafesubscribe and not used because it would add a sigificent depth to Alreay Hu GE call stacks.Try{//Allow the hook to intercept and/or decorate hook.onsubscribestart (this, onsubscribe). Call (SUBSC Riber);returnHook.onsubscribereturn (subscriber); } catch (Throwable e) {//Special handling forCertain throwable/error/exception types Exceptions.throwiffatal (e); //ifAn unhandled error occurs executing the onsubscribe we'll propagate itTry{Subscriber.onerror (Hook.onsubscribeerror (e)); } catch (onerrornotimplementedexception E2) {//special handling when onError are not implemented...We just rethrow throw E2; } catch (Throwable e2) {//ifThis happens it means the OnError itself failed (perhaps an invalidfunctionImplementation)//So we were unable to propagate the error correctly and would just throw Run Timeexception r = New RuntimeException ("Error occurred attempting to subscribe ["+ e.getmessage () +"] and then again while trying to pass to OnError.", E2); TODO could the hook be the cause of the errorinchThe On error handling.                Hook.onsubscribeerror (R); TODO why aren' t we throwing the hook 'SreturnValue.            Throw R; }returnSubscriptions.unsubscribed (); }    }

Method Hook.onsubsribestart (this, onsubscribe). Call (subscriber) is equivalent to Onsubscribe.call (subscriber) by default. What is Onsubscriber? This requires an understanding of how the Behaviorsubject is constructed.

protectedBehaviorSubject(OnSubscribe<T> onSubscribe, SubjectSubscriptionManager<T> state) {    super(onSubscribe);    this.state = state;}

Where the constructor of the parent class subject is called

protectedSubject(OnSubscribe<R> onSubscribe) {    super(onSubscribe);}

Where the constructor of the parent class observer is called

protectedObservable(OnSubscribe<T> f) {    this.onSubscribe = f;}

Obsubscribe is the first parameter passed in the Behaviorsubject construction method.

Behaviorsubject has 3 static factory methods for producing Behaviorsubject objects.

 Public Final  class behaviorsubject<t> extends Subject<t, T> {     Public Static<T> behaviorsubject<t> Create () {returnCreateNULL,false); } Public Static<T> behaviorsubject<t> Create (T defaultvalue) {returnCreate (DefaultValue,true); }Private Static<T> behaviorsubject<t> Create (T defaultvalue,BooleanHasDefault) {Finalsubjectsubscriptionmanager<t> State =NewSubjectsubscriptionmanager<t> ();if(HasDefault)        {State.set (Notificationlite.instance (). Next (defaultvalue)); } state.onadded =NewAction1<subjectobserver<t>> () {@Override Public voidCall (Subjectobserver<t> o) {O.emitfirst (State.get (), state.nl);        }        }; state.onterminated = state.onadded;return NewBehaviorsubject<t> (State, state); }    ....}

The static constructor method of the first two public actually calls the third private method.
The last return is new behaviorsubject<t> (state, state), so Onsubscribe is actually a Subjectsubscriptionmanager object, Onsubscribe.call (subscriber) actually calls the call method of Subjectsubscriptionmanager.

/ * Package * /Final  class Subjectsubscriptionmanager<T> implements Onsubscribe <T> {... @Override Public voidCallFinalsubscriber<?SuperT> child) {subjectobserver<t> Bo =NewSubjectobserver<t> (child);        Addunsubscriber (Child, Bo); Onstart.call (BO);if(!child.isunsubscribed ()) {if(Add (Bo) && child.isunsubscribed ())            {Remove (BO); }        }    }}

1. Call the Addunsubscriber method to register an action that executes when the subscription is canceled, removing the observer from the viewer.

/** Registers the unsubscribe action for the given subscriber. */voidsuperfinal SubjectObserver<T> bo) {    child.add(Subscriptions.create(new Action0() {        @Override        publicvoidcall() {            remove(bo);        }    

2. Call the Add (subjectobserver<t> O) method to add the observer to the registered observer[] array.

boolean add(SubjectObserver<T> o) {    do {        State oldState = state;        if (oldState.terminated) {            onTerminated.call(o);            returnfalse;        }        State newState = oldState.add(o);        if (STATE_UPDATER.compareAndSet(this, oldState, newState)) {            onAdded.call(o);            returntrue;        }    while (true);}

The method calls Onadd.call (O). Behaviorsubject's Onadd object is as follows, State.get () Gets the nearest data object, and O.emitfirst releases the nearest data object, which is a reflection of the Behaviorsubject feature.

new Action1<SubjectObserver<T>>() {    @Override    publicvoidcall(SubjectObserver<T> o) {        o.emitFirst(state.get(), state.nl);    }};

In this process, two internal classes of Subjectsubscriptionmanager are used.
1. state<t>
This class is used to manage the observer arrays that are already registered, as well as their state.

/** State-machine representing the termination state and active subjectobservers. * *protected StaticFinalclassstate<t> {Final Boolean terminated; Final subjectobserver[] observers;StaticFinal subjectobserver[] No_observers =Newsubjectobserver[0];StaticFinal state TERMINATED =NewState (true, no_observers);StaticFinal state EMPTY =NewState (false, no_observers); Public  State(Boolean terminated, subjectobserver[] observers) { This. terminated = terminated; This. observers = observers; } PublicStateAdd(Subjectobserver o) {        ...    } PublicStateRemove(Subjectobserver o) {        ...    }}

2.subjectobserver<t>

This class when the observer of a decorative class, the use of decorative mode to the Observer class to add new features.

This is the process when the subject object subscribes to observer.

2.2.2 Behaviorsubject's OnNext

The Behavior OnNext (T V) method is as follows

@Overridepublic void onNext(T v) {    laststate.get();    if (laststate.active) {        Object n = nl.next(v);        forstate.next(n)) {            state.nl);        }    }}

State is the object of the Subjectsubscriptionmanager class, which is the object that maintains the recently freed data object, State.get () Gets the recently freed data object, State.next (object N) The Observer method re-sets the most recently freed data object and returns an array of already registered arrays.

SubjectObserver<T>[] next(Object n) {    set(n);    return state.observers;}

Bo.emitnext (object N, Final notificationlite<t> NL) Releases the given data object.

2.2.3 Behaviorsubject's oncompleted and onerror

OnCompleted and OnError call Subjectsubscriptionmanager's Terminate (object N) method, which will reset the recently freed data object and set the subject status to terminated , which indicates the end, and finally returns the registered observer array.

SubjectObserver<T>[] terminate(Object n) {    set(n);    false;    State<T> oldState = state;    if (oldState.terminated) {        return State.NO_OBSERVERS;    }    return STATE_UPDATER.getAndSet(this, State.TERMINATED).observers;}

Copyright NOTICE: This article is the original blogger article, reprint please indicate the source http://blog.csdn.net/sun927

Rxjava Analysis-subject

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.