A thorough understanding of Rxjava (i) basic knowledge

Source: Internet
Author: User

A thorough understanding of Rxjava (i) basic knowledge

--Welcome Reprint, please specify the source http://blog.csdn.net/asce1885, without my consent do not use for commercial purposes, thank you--

Original link: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

This article Gitbooks link: http://asce1885.gitbooks.io/android-rd-senior-advanced/content/che_di_le_jie_rxjava_ff08_yi_ff09_ Ji_chu_zhi_shi.html

Rxjava is currently a popular library of functions among Android developers. The only problem is that it's harder to understand when you first get into touch. Function-responsive programming is hard to understand for developers outside the world, but once you understand it, you'll feel great.

I will introduce some of Rxjava's knowledge, and the goal of this series (four parts) is to bring you into the Rxjava gate. I won't explain all the relevant points of knowledge (I can't do it), I just want to arouse your interest in Rxjava and know how it works.

Basic knowledge

The basic component of the responsive code is observables and subscribers (in fact Observer is the smallest building block, but the most used in practice is subscriber, because Subscriber is the counterpart of Observables. )。 Observable sends messages, while Subscriber is used to consume messages.

The message is sent in a fixed mode. Observable can send any number of messages (including empty messages), and when a message is successfully processed or an error occurs, the process ends. Observable will call each of its subscriber Subscriber.onnext () functions and End with Subscriber.oncomplete () or Subscriber.onerror ().

This looks like the standard observer pattern, but a different key point is that observables typically only start sending messages when subscriber subscribe to it (the term is hot-start observable and cold-start observable. Hot start observable messages are sent at any time, even if no observer listens to it. Cold start observable messages are sent only when there is at least one subscriber (in my case, there is only one subscriber). This difference is not important to start learning Rxjava. )。 In other words, if no subscriber observes it, it will not work.

Hello, world!.

Let's actually look at this framework in a concrete example. First, we create a basic observable:

Observable<String> myObservable = Observable.create(    new Observable.OnSubscribe<String>() {        @Override        sub) {            sub.onNext("Hello, world!");            sub.onCompleted();        }    });

Our observable sends "hello,world!" The message is then completed. Now let's create subscriber to consume this data:

new Subscriber<String>() {    @Override    publicvoidonNext(String s) { System.out.println(s); }    @Override    publicvoidonCompleted() { }    @Override    publicvoidonError(Throwable e) { }};

The work done by the above code is to print a string sent by observable. Now that we have myobservable and Mysubscriber, we can associate the two with the subscribe () function:

myObservable.subscribe(mySubscriber);//Outputs"Hello, world!"

When the subscription is complete, myobservable will call subscriber's OnNext () and OnComplete () functions, eventually mysubscriber print "Hello, world!" And then terminates.

More Concise Code

Above in order to print "Hello, world!" A lot of boilerplate code is written to give you a detailed understanding of what's going on. Rxjava provides a number of quick ways to make coding easier.

First let's simplify Observable,rxjava to provide many built-in observable creation functions for common tasks. In the following example, Observable.just () sends a message and completes it, functionally similar to the code above (strictly speaking, the Observable.just () function is not exactly the same as our original code, but I will not explain why before the third part of this series):

Observable<String> myObservable =    Observable.just("Hello, world!");

Next, let's deal with subscriber unnecessary boilerplate code. If we don't care about oncompleted () or onerror (), then you can use a simpler class to define what functions to accomplish during the OnNext ():

new Action1<String>() {    @Override    publicvoidcall(String s) {        System.out.println(s);    }};

Actions can define each part of the subscriber, and the Observable.subscribe () function can handle one, two or three action arguments, representing OnNext (), OnError (), and OnComplete () respectively Function. The above subscriber is now shown below:

myObservable.subscribe(onNextAction, onErrorAction, onCompleteAction);

However, now we don't need the onerror () and OnComplete () functions, so we only need the first parameter:

myObservable.subscribe(onNextAction);//Outputs"Hello, world!"

Now, let's link the above function call to remove the temporary variable:

Observable.just("Hello, world!")    .subscribe(new Action1<String>() {        @Override        publicvoidcall(String s) {              System.out.println(s);        }    });

Finally, we use the Java 8 lambdas expression to get rid of the ugly Action1 code:

Observable.just("Hello, world!")    .subscribe(s -> System.out.println(s));

If you are on the Android platform (and therefore cannot use Java 8), then I highly recommend using RETROLAMBDA, which will greatly reduce the redundancy of the code.

Transform

Let's have some excitement. If I wanted to stitch my signature into the "Hello, world!" output. One possible way is to change the observable:

Observable.just("Hello, world! -Dan")    .subscribe(s -> System.out.println(s));

This is possible when you have permission to control observable, but there is no guarantee that this can happen every time, if you are using someone else's library of functions. Another possible question is: What if you use observable in multiple places in your project, but you only need to add signatures somewhere?

How do we try to modify subscriber?

Observable.just("Hello, world!")    .subscribe(s -> System.out.println" -Dan"));

This solution is not satisfactory, but the reason is different from the above: I want to subscribers as lightweight as possible, because I might want to run it in the main thread. At a more conceptual level, subscribers is used for passive responses rather than unsolicited messages to make other objects change.
If you can pass some intermediate steps to the above "Hello, world!" Wouldn't it be cool to convert?

Operators Introduction

Next we'll show you how to solve the problem of message transformation: using Operators. Operators plays a role in manipulating messages between the message sender observable and the message consumer Subscriber. Rxjava has a lot of opetators, but at first it's best to start with a small part.
In this case, map () operator can be used to convert a message that has been sent to another form:

Observable.just("Hello, world!")    .map(new Func1<StringString>() {        @Override        publicString call(String s) {            return+" -Dan";        }    })    .-> System.out.println(s));

Similarly, we can use the Java 8 lambdas expression to simplify the code:

Observable.just("Hello, world!")    .map" -Dan")    .subscribe(s -> System.out.println(s));

Pretty cool, huh? Our map () operator is essentially a observable for translating message objects. We can cascade calls to any number of map () functions, one layer at a layer, to transform the initial message into the data form required by subscriber.

More explanations for map ()

The interesting point of the map () function is that it does not need to send the same data type as the original observable. If my subscriber does not want to output the original string directly, but wants to output the hash value of the original string:

observable    Just ( "Hello, world!" )  map  (new  func1<          String , integer  >  () {@Override public  integer  call (string  s) {return  s        Hashcode (); }})  Subscribe (i ->  system Out println (integer   ToString (i)));  

Interestingly, our original input was a string, but subscriber eventually received an integer type. Similarly, we can use Lambdas to simplify the code as follows:

Observable.just("Hello, world!")    .map(s -> s.hashCode())    .subscribe(i -> System.out.println(Integer.toString(i)));

As I said earlier, I want subscriber to do as little work as possible, and we can move the hash value into a string into a new map () function:

Observable.just("Hello, world!")    .map(s -> s.hashCode())    .map(i -> Integer.toString(i))    .subscribe(s -> System.out.println(s));

Don't you want to see this? Our observable and subscriber changed back to the original code. We just added some transformation steps in the middle, and I can even add my signature transformation back:

Observable.just("Hello, world!")    .map" -Dan")    .map(s -> s.hashCode())    .map(i -> Integer.toString(i))    .subscribe(s -> System.out.println(s));
So what?

Here you might think, "there are a lot of clever tricks to get the simple code." Indeed, this is a simple example, but there are two concepts you need to understand:

Key concepts #1:observable and subscriber can accomplish anything.

Flying your imagination, everything is possible.
Your observable can be a database query, subscriber get the query results and then display it on the screen. Your observable can be a click on the screen, subscriber respond to the event. Your observable can read a byte stream from the network and Subscriber write it to the local disk.
This is a universal framework that can handle anything.

The key concepts #2:observable and subscriber are independent of each other in a series of conversion steps between them.

We can add any number of desired map () functions between the message sender observable and the message consumer Subscriber. The system is highly composable: it can easily manipulate data. As long as the operators conforms to the input and output data type, then I can get an endless call chain (well, not endless, because it always reaches the limit of the physical machine, but you know what I want to say).

With two key concepts, you can see a system with great potential. But here we only introduce a operator:map (), which severely limits our possibilities. In the second part of this series, we will detail the large number of operators available in Rxjava.

--Welcome Reprint, please specify the source http://blog.csdn.net/asce1885, without my consent do not use for commercial purposes, thank you--

A thorough understanding of Rxjava (i) basic knowledge

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.