Preliminary study on Rxjava Observeon () and Subscribeon ()

Source: Internet
Author: User
Tags throw exception throwable

How can rxjava such a powerful class library not have multi-threaded switching?

where Observeon () and Subscribeon () are to achieve such a role. This article mainly explains the usage of Observeon () and Subscribeon (), and does not explore the principle.

0. Default condition

By default, it does not do any threading, observable and observer are on the same thread, do not do any thread switching, and then execute as shown in the following sequence:

You can write a demo test:

Observable<string> Source = Observable.just ("Alpha", "Beta", "Gamma"); SOURCE. Subscribe (NewSubscriber<integer>() {@Override Public voidoncompleted () {} @Override Public voidOnError (Throwable e) {} @Override Public voidonNext (Integer integer) {log.i ("TAG", "Received" + integer + "on thread:" +Thread.CurrentThread (). GetName ()); }        });
1. The role of Subscribeon ()

This method is the thread that indicates the data is generated, that is, the thread where the observable emitted data is located, and if nothing is done afterwards, the operator operator (such as MAP,FLATMAP, etc.) also handles the processing of the specified thread Subscribeon.

Multiple uses of Subscribeon () do not frequently switch threads, only one of the closest Subscribeon () to the data source determines which thread the data source is emitting data from. As shown in the code:

Observable<string> Source = Observable.just ("Alpha", "Beta", "Gamma"); Source.subscribeon (Schedulers.computation ()). Subscribeon (Schedulers.newthread ()). Subscribe (NewSubscriber<integer>() {@Override Public voidoncompleted () {} @Override Public voidOnError (Throwable e) {} @Override Public voidonNext (Integer integer) {log.i ("TAG", "OnNext:" + "on Thread:" +Thread.CurrentThread (). GetName ());    }        }); }

Only Subscribeon (Schedulers.computation ()) has a function on the DataSource source, which emits data on the thread specified in Schedulers.computation (). If Observeon () is not used later, the operator operator will do the data transformation on the thread specified by Schedulers.computation ().

2. The role of Observeon ()

In Android development, we often face the scenario of generating data in a worker thread, updating the corresponding View,subscribeon () in the UI thread, specifying the thread that the data is emitted from, but we are updating the UI and it is not possible to run on the thread that is transmitting the data. This can cause problems with the ANR. At this point, the thread switch must be done through the Observeon () method:

Observable<string> Source = Observable.just ("Alpha", "Beta", "Gamma"); Source.map (NewFunc1<string, integer>() {@Override PublicInteger Call (String s) {log.i ("TAG", "Call:" +Thread.CurrentThread (). GetName ()); returns.length ();                }}). Observeon (Schedulers.newthread ()). Subscribeon (Schedulers.computation ()). Subscribe (NewSubscriber<integer>() {@Override Public voidoncompleted () {} @Override Public voidOnError (Throwable e) {} @Override Public voidonNext (Integer integer) {log.i ("TAG", "OnNext:" + "on Thread:" +Thread.CurrentThread (). GetName ()); }        });

The result of the above code is as follows:

Tag:call:rxcomputationscheduler-1TAG:onNext:on Thread:rxnewthreadscheduler-1tag:call: Rxcomputationscheduler-1TAG:onNext:on thread:rxnewthreadscheduler-1tag:call: Rxcomputationscheduler-1TAG:onNext:on Thread:rxnewthreadscheduler-1

As you can see, the operation before Observeon () runs on the thread specified by Subscribeon (Schedulers.computation ()), which is the RxComputationScheduler-1 thread After the Observeon () is used, the operation after it is

Runs on a thread specified by Observeon (Schedulers.newthread ()).

So, give a conclusion that Observeon () only works on its subsequent operations; Observeon () can be used more than once, and each time it works on the operator after it has no effect on the previous operation.

A good interpretation of the role of Observeon.

3. Problems with Backpressure

Due to the role of Observeon, data streams are continuously transmitted across multiple threads, and there may be a speed mismatch. As shown, when the data stream at the bottom is faster than the processing speed of the top data stream, if an exception occurs, some data may not be processed by the top subscriber.

Too much nonsense, not clear, look at the code:

Observable<string> Source = Observable.just ("Alpha", "Beta", "Gamma"); Source.map (NewFunc1<string, integer>() {@Override PublicInteger Call (String s) {log.i ("TAG", "Call:" +Thread.CurrentThread (). GetName ()); if(S.equals ("Gamma"))                    Throw Newruntimeexception (); returns.length (); }}). Doonerror (NewAction1<throwable>() {@Override Public voidCall (Throwable throwable) {log.i ("TAG", "Doonerror:" +Thread.CurrentThread (). GetName ()); }}). Observeon (Schedulers.newthread ()). Subscribeon (Schedulers.computation ()). Subscribe (NewSubscriber<integer>() {@Override Public voidoncompleted () {} @Override Public voidOnError (Throwable e) {log.i ("TAG", "OnError:" + "on Thread:" +Thread.CurrentThread (). GetName ()); } @Override Public voidonNext (Integer integer) {log.i ("TAG", "OnNext:" + "on Thread:" +Thread.CurrentThread (). GetName ());    }        }); }

Look at the results of the operation:

Tag:call:rxcomputationscheduler-1TAG:call:RxComputationScheduler-1TAG:call:RxComputationScheduler -1TAG:doOnError:RxComputationScheduler-1TAG:onError:on Thread:rxnewthreadscheduler-1

We can see that when the emitted data is a gamma throw exception, before the data emitted "Alpha", "Beta" has not been subsriber OnNext method, this is backpressure problem.

4. Onerrorresumenext

Onerrorresumenext is a method of error recovery, when an operator in our data chain throws an exception, it interrupts the entire data chain, but we want to try to recover it, then we can use

Onerrorresumenext. For example, when Android is logged in too frequently, a dialog (popup window) will pop up, allowing the user to enter a verification code that can be processed in Onerrorresumenext.

Let's look at a piece of code first:

Observable<string> Source = Observable.just ("Alpha", "Beta", "Gamma"); Source.map (NewFunc1<string, integer>() {@Override PublicInteger Call (String s) {log.i ("TAG", "Call:" +Thread.CurrentThread (). GetName ()); if(S.equals ("Gamma"))                    Throw Newruntimeexception (); returns.length ();                }}). Observeon (Schedulers.newthread ()). Subscribeon (Schedulers.computation ()) . Onerrorresumenext (NewFunc1<throwable, observable<?extendsInteger>>() {@Override Publicobservable<?extendsInteger>Call (Throwable throwable) {returnObservable.just (+). Map (NewFunc1<integer, integer>() {@Override Publicinteger call (integer integer) {log.i ("TAG", "Call:onerrorresumenext:" +Thread.CurrentThread (). GetName ()); returninteger;            }}) . Subscribeon (Schedulers.computation ()); }}). Subscribe (NewSubscriber<integer>() {@Override Public voidoncompleted () {} @Override Public voidOnError (Throwable e) {log.i ("TAG", "OnError:" + "on Thread:" +Thread.CurrentThread (). GetName ()); } @Override Public voidonNext (Integer integer) {log.i ("TAG", "OnNext:" + "on Thread:" +Thread.CurrentThread (). GetName ()); }                });

Looking at the section of the code in the Onerrorresumenext part, why in Onerrorresumenext can again use the Subscribeon (), my guess (and did not see the source) may be that the code generated a new data source, So you can use Subsribeon () to specify the thread that the data source emits data from.

The result of its operation:

Tag:call:rxcomputationscheduler-1TAG:call:RxComputationScheduler-1TAG:call:RxComputationScheduler -1TAG:onNext:on thread:rxnewthreadscheduler-1TAG:onNext:on Thread:rxnewthreadscheduler-1 TAG:call:onErrorResumeNext:RxComputationScheduler-2TAG:onNext:on Thread:rxcomputationscheduler -2

See the results of the operation in the Onerrorresumenext method using the Subscribeon (), the thread switched to RxComputationScheduler-2, in the absence of Observeon after the case, The last OnNext also runs on the RxComputationScheduler-2. It's amazing,!!!!!.

Rxjava Observeon () and Subscribeon ()

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.