Rxjava Subscription Automatic Unsubscribe __java

Source: Internet
Author: User
Tags error handling getmessage throwable hello subscription

In the context of the relationship between Rxjava Observer and subscriber, we mentioned that:

The results of subscribe (mobserver) and subscribe (Msubscriber) are different: subscribe (msubscriber) This subscription is not performed the second time the data is requested. The reason is that the subscription is automatically canceled after the first onnext, and subscribe (mobserver) does not appear.

Today we analyze the reason.

First take a look at the source code.

Subscription
There is an interface called subscription in the Rxjava that can be used to unsubscribe.

Public interface Subscription {
    /**
     * Stops "receipt of notifications on the" {@link subscriber} that is regist Ered when this Subscription
     * is received.
     * <p>
     * This allows unregistering a {@link subscriber} before it has finished receiving all events (i.e. before
     * oncompleted is called).
     * *
    void unsubscribe ();

    /**
     * Indicates whether this {@code Subscription} is currently unsubscribed.
     *
     * @return {@code true} if this {@code Subscription} is currently unsubscribed, {@code false} otherwise
     */
  
   boolean isunsubscribed ();
}
  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

As you can see from the above, we just need to call unsubscribe to unsubscribe, so how do we get a subscription object?

It's actually very simple:
The Observable.subscribe () method returns a subscription object, that is, each subscription will be returned.
Feel subscription is like an order, you will generate an order, and you can use this order to cancel the order. actual Combat

I first wrote the following code to test:

Subscription Subscription = Observable.just ("Hello Subscription")
        . Subscribe (New action1<string> () {
            @ Override public
            void Call (String s) {
                System.out.println (s);
            }
        });
System.out.println (subscription.isunsubscribed ());
Subscription.unsubscribe ();
System.out.println (subscription.isunsubscribed ());
1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9-10

The log that I want to output should be like this:

Hello Subscription
false
True
1 2 3 1 2 3

But the result was unexpected, and I was running after it:

Hello Subscription
true
1 2 3 1 2 3

Obviously I did not cancel the subscription ah, how is true?

Then I went into the source to explore the discovery:
In Observable.subscribe () Source:

Public final Subscription Subscribe (subscriber&lt. Super t> subscriber) {return Observable.subscribe (subscrib
    Er, this);
     Static <T> Subscription Subscribe (subscriber< Super t> Subscriber, observable<t> observable) {  Validate and proceed if (subscriber = null) {throw new IllegalArgumentException ("Observer can
        Not being null "); } if (observable.onsubscribe = = null) {throw new IllegalStateException ("Onsubscribe function can not
            be null. ");
             * * The Subscribe function can also be overridden but generally that's not the appropriate approach
        * So I won ' t mention of the exception//new Subscriber so onStart it

        Subscriber.onstart ();
         * * https://github.com/ReactiveX/RxJava/issues/216 for discussion on "guideline 6.4:protect calls * To user code from within an Observer "* *
        If not already wrapped if (!) (
            Subscriber instanceof Safesubscriber)) {//Assign to ' observer ' so we return the protected version
        Subscriber = new safesubscriber<t> (subscriber); }//The code below is exactly the same of unsafesubscribe but not used because it would//add a signif
        Icant depth to already huge call stacks. try {//allow the hooks to intercept and/or decorate hook.onsubscribestart (observable, observable.
            Onsubscribe). Call (subscriber);
        Return Hook.onsubscribereturn (subscriber); catch (Throwable e) {//special handling for certain throwable/error/exception types exceptions
            . Throwiffatal (e);
                The subscriber can ' t listen to exceptions anymore if (subscriber.isunsubscribed ()) {
            Rxjavapluginutils.handleexception (Hook.onsubscribeerror (e)); else {//IF An unhandled error occurs executing the onsubscribe we propagate it try {SUBSC
                Riber.onerror (Hook.onsubscribeerror (e));
                    catch (throwable E2) {exceptions.throwiffatal (E2); If this is happens it means the OnError itself failed (perhaps an invalid function implementation)// So we are unable to propagate the error correctly and would just throw r = new RuntimeException Failedexception ("Error occurred attempting to subscribe [" + e.getmessage () + "] and then again while trying to
                    Error. ", E2);
                    TODO could the hook is the cause of the error in the "error handling."
                    Hook.onsubscribeerror (R);
                    TODO why aren ' t we throwing the hook ' s return value.
                Throw R;
        } return subscriptions.unsubscribed (); }
    }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26-27--28 29---30 31--32 33 34 35 36 37 38-39 40 41 42 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 1 2 3 4 5 6 7 8 9 10-11--12 13---14 15--16 17 18 19 20 21 22-23 24 25 26 8 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

Key code:

if (!) ( Subscriber instanceof Safesubscriber)) {
    //Assign to ' observer ' so we return the protected version
    Subscriber = n EW safesubscriber<t> (subscriber);
}
1 2 3 4 1 2 3 4

It will transfer our subscriber into the Safesubscriber,safesubcriber source code as follows:

public class Safesubscriber<t> extends subscriber<t> {private final subscriber< Super t> actual;

    Boolean done = false;
        Public Safesubscriber (SUBSCRIBER&LT; Super t> Actual) {Super (Actual);
    This.actual = actual;
     }/** * Notifies the subscriber that {@code observable} has finished sending push-based.
     * <p> * The {@code observable} would not be call this if it calls {@link #onError}.
            */@Override public void oncompleted () {if (!done) {done = true;
            try {actual.oncompleted ();
                The catch (Throwable e) {//We handle here instead of another method so we don ' t add stacks to the frame
                which can prevent it from being able to handle StackOverflow (e);
                Rxjavapluginutils.handleexception (e); throw new oncompletedfailedException (E.getmessage (), E); Finally {try {//similarly to OnError if failure occurs in unsubscribe then Rx con
                    Tract is broken//and we throw a unsubscribefailureexception.
                Unsubscribe ();
                    catch (Throwable e) {rxjavapluginutils.handleexception (e);
                throw new Unsubscribefailedexception (E.getmessage (), E); }}/** * Notifies the Subscriber that the {@code observable} has experienced a err
     or condition. * <p> * If the {@code observable} calls this method, it won't thereafter call {@link #onNext} or * {@li
     NK #onCompleted}. * * @param e * The exception encountered by the observable/@Override public void Onerr or (Throwable e) {//We handle here instead of another method so we don ' t add stacks to the frame//WHich can prevent it from being able to handle StackOverflow (e);
            if (!done) {done = true;
        _OnError (e);
     }/** * Provides the subscriber with a new item to observe.
     * <p> * The {@code observable} may call this is 0 or more times. * <p> * The {@code observable} would not call this

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.