A thorough understanding of RxJava (1) Basic knowledge and RxJava () Basic knowledge

Source: Internet
Author: User

A thorough understanding of RxJava (1) Basic knowledge and RxJava () Basic knowledge
A thorough understanding of RxJava (1) Basic knowledge

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

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

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 a popular function library for Android Developers. The only problem is that it is hard to understand at the beginning. Function responsive programming is hard to understand for developers in the "outside world", but once you understand it, you will feel great.

I will introduce some knowledge about RxJava. The goal of this series of articles (part 4) is to bring you to the door of RxJava. I won't explain all the relevant knowledge points (I can't do it). I just want to arouse your interest in RxJava and know how it works.

Basic knowledge

The basic components of responsive code are Observables and Subscribers (in fact, Observer is the smallest building block, but in practice, Subscriber is used most, because Subscriber is the corresponding to Observables .). The Observable sends messages, while the Subscriber is used to consume messages.

Messages are sent in a fixed mode. The Observable can send any number of messages (including empty messages). When a message is successfully processed or fails, the process ends. Observable calls the Subscriber. onNext () function of each Subscriber and ends with Subscriber. onComplete () or Subscriber. onError.

This looks like a standard observer mode, but the key difference is that Observables generally start to send messages only when Subscriber subscribes to it (in terms of Hot-start Observable and cold-start Observable. The hot-start Observable sends a message at any time, even if no observer listens to it. Cold-start Observable sends messages only when at least one subscriber exists (in my example, there is only one subscriber ). This difference is not important for learning RxJava .). In other words, if no subscriber observes it, it will not take any effect.

Hello, World!

Let's take a concrete example to look at this framework. First, we create a basic Observable:

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

Our Observable sends "Hello, world !" The message is completed. Now let's create a Subscriber to consume this data:

Subscriber<String> mySubscriber = new Subscriber<String>() {    @Override    public void onNext(String s) { System.out.println(s); }    @Override    public void onCompleted() { }    @Override    public void onError(Throwable e) { }};

The above code is used to print the strings sent by the Observable. Now that we have myObservable and mySubscriber, we can associate them through the subscribe () function:

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

After the subscription is complete, myObservable will call the onNext () and onComplete () functions of subscriber, and then mySubscriber will print "Hello, world !" Then terminate.

Simpler code

In order to print "Hello, world !" I wrote a lot of sample code to give you a detailed understanding of what happened. RxJava provides many shortcuts to simplify coding.

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

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

Next, let's process the unnecessary sample code of Subscriber. If we don't care about onCompleted () or onError (), we can use a simpler class to define what functions will be done during onNext:

Action1<String> onNextAction = new Action1<String>() {    @Override    public void call(String s) {        System.out.println(s);    }};

Actions can define each part of a Subscriber. the Observable. subscribe () function can process one or two or three Action parameters, representing onNext (), onError (), and onComplete () functions respectively. The above Subscriber is as follows:

myObservable.subscribe(onNextAction, onErrorAction, onCompleteAction);

However, now we do not 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        public void call(String s) {              System.out.println(s);        }    });

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

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

If you are on the Android platform (so you cannot use Java 8), I strongly recommend using mongolambda, which will greatly reduce code redundancy.

Transform

Let's have some excitement. If I want to splice my signature to "Hello, world! . One feasible method is to change the Observable:

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

This is feasible when you have the permission to control the Observable, but it cannot be guaranteed that this can be done every time. What if you are using another user's function library? Another possible problem is: What if the project uses Observable in multiple places but only needs to add a signature somewhere?

What if we try to modify the Subscriber?

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

This solution is not satisfactory, but the reason is different from the above: I want Subscribers to be as lightweight as possible, because I may have to run it in the main thread. In a more conceptual sense, Subscribers is used for passive responses, rather than actively sending messages to change other objects.
If you can use some intermediate steps to match "Hello, world !" Isn't that cool?

Operators Introduction

Next we will introduce how to solve the problem of message conversion: Operators. Operators can manipulate messages between the message sender Observable and the message consumer Subscriber. RxJava has a large number of opetators, but it is best to get familiar with it from a small part at the beginning.
In this case, map () operator can be used to convert sent messages into another form:

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

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

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

Cool, right? Our map () operator is essentially an Observable used to convert message objects. We can call any number of map () functions in a cascading manner to convert the initial message to the data format required by Subscriber one by one.

Map () more explanations

The interesting thing about 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 directly output the original string, 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 is a string, but the Subscriber finally receives an Integer. 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 mentioned earlier, I want Subscriber to do as little work as possible. We can convert the hash value into a string and move it to 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 take a look at this? Our Observable and Subscriber are changed back to the original code. We just added some transformation steps in the middle. I can even add my signature conversion back:

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

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

Key Concept #1: Observable and Subscriber can accomplish anything.

Let go of your imagination. Everything is possible.
Your Observable can be a database query. Subscriber obtains the query result and displays it on the screen. Your Observable can be a click on the screen, and the Subscriber responds to this event. Your Observable can read a byte stream from the network, and Subscriber writes it to a local disk.
This is a general framework that can handle everything.

Key Concept #2: The conversion steps between Observable and Subscriber are independent of each other.

We can add any number of map () functions between the message sender Observable and the message consumer Subscriber. This system is highly composable: it is easy to manipulate data. As long as operators meets the input/output data type, I can get an endless call chain (well, it's not an endless call chain, because it will always reach the limit of the physical machine, but you know what I want to say ).

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

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

Related Article

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.