Introduction to Android RxJava (2) Operators of RxJava

Source: Internet
Author: User

Introduction to Android RxJava (2) Operators of RxJava

In the previous article, we used a simple example to show you the basic usage of RxJava. I believe that you have a general understanding of RxJava. Since the previous article introduced the use of RxJava, it hasn't been further expanded. Maybe you have a sense of real name for RxJava. OK. Now let's get started and unveil the secrets of RxJava step by step!

Example

RxJava provides rich and powerful operators. By using and combining these operators, you can complete almost all the tasks you want to accomplish. For example:

Now there is a requirement: When the app is started, an image (generally the app logo) is displayed, which is what we call the welcome page. The page automatically jumps to the homepage 2-3 seconds later. Isn't that the requirement for starting pages for almost every app? The Code is as follows:
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_welcome);        ImageView view = (ImageView) findViewById(R.id.iv_welcome);        view.setImageResource(R.drawable.welcome);        Handler handler = new Handler();        handler.postDelayed(new Runnable() {            @Override            public void run() {                startActivity(new Intent(WelcomeActivity.this, MainActivity.class));                finish();            }        },2000);    }

The Code of RxJava is implemented as follows:

protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_welcome);        ImageView view = (ImageView) findViewById(R.id.iv_welcome);        view.setImageResource(R.drawable.welcome);        Observable.timer(2, TimeUnit.SECONDS, AndroidSchedulers.mainThread()).map(l->{            startActivity(new Intent(this, MainActivity.class));            finish();            return null;        }).subscribe();    }

Here RxJava uses two operators: one is the timer operator, which means to delay the execution of an operation; the other is the map operator, which means to convert an execution result.
Well, it seems that apart from different writing methods, RxJava has no advantages. Okay. Continue!
2. as the product is going to be active recently, in order to display the activity content to users in a prominent position, after discussion, we will stay on the welcome page for 2 seconds, to jump to the activity content page (that is, an advertisement image), and then stay on the activity content page for 2-3 seconds, then jump to the home page;

Protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_welcome); ImageView view = (ImageView) findViewById (R. id. iv_welcome); view. setImageResource (R. drawable. welcome); // open a new thread to obtain the image from the network. AsyncAdImageFromNet (); Handler handler = new Handler (); handler. postDelayed (new Runnable () {@ Override public void run () {// mAdBitmapDrawable is an image obtained from the network If the image is obtained, it will be displayed. Otherwise, the page will jump directly to the homepage if (mAdBitmapDrawable! = Null) {view. setImageDrawable (mAdBitmapDrawable); handler. postDelayed (new Runnable () {@ Override public void run () {startActivity (new Intent (WelcomeActivity. this, MainActivity. class); finish (); }}, 2000);} else {startActivity (new Intent (WelcomeActivity. this, MainActivity. class); finish () ;}}, 2000 );}

This Code does not take offline into account, that is, no active content image is displayed without the network. It is best to download the image to the local cache when there is a network, the improved code is as follows:

Protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_welcome); ImageView view = (ImageView) findViewById (R. id. iv_welcome); view. setImageResource (R. drawable. welcome); // local image cache path File localBitmapFile = new File (getLocalBitmapPath (); if (localBitmapFile. exists () mAdBitmapDrawable = BitmapFactory. decodeFile (localBitmapFile); // open a new thread from the network Obtain the image AsyncAdImageFromNet (); Handler handler = new Handler (); handler. postDelayed (new Runnable () {@ Override public void run () {// mAdBitmapDrawable is the image obtained from the local cache. If the image is obtained, it is displayed, otherwise, go directly to the homepage if (mAdBitmapDrawable! = Null) {view. setImageDrawable (mAdBitmapDrawable); handler. postDelayed (new Runnable () {@ Override public void run () {startActivity (new Intent (WelcomeActivity. this, MainActivity. class); finish (); }}, 2000);} else {startActivity (new Intent (WelcomeActivity. this, MainActivity. class); finish () ;}}, 2000 );}

Take a closer look, there is still a problem with the Code. loading the local cache image will block the main thread if the image is large. It is best to put the locally loaded cache image in one thread for execution, the code is getting messy. Let's see how RxJava is used?

Protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_welcome); ImageView view = (ImageView) findViewById (R. id. iv_welcome); view. setImageResource (R. mipmap. welcome); Observable. mergeDelayError (// load the local cached image loadBitmapFromLocal () in the new thread (). subscribeOn (Schedulers. io (), // load the network image loadBitmapFromNet () in the new thread (). subscribeOn (Schedulers. newThread (), Observable. timer (3, TimeUnit. SECONDS ). map (c-> null) // obtains the loaded data every 2 seconds. sample (2, TimeUnit. SECONDS, AndroidSchedulers. mainThread ()). flatMap (r-> {if (r = null) // if no image is obtained, go directly to the home page and return Observable. empty (); else {// If an image is obtained, it will take 2 seconds to jump to the home page view. setImageDrawable (r); return Observable. timer (2, TimeUnit. SECONDS );}}). subscribe (r->{}, e-> {startActivity (new Intent (WelcomeActivity. this, MainActivity. class); finish () ;}, ()-> {startActivity (new Intent (WelcomeActivity. this, MainActivity. class); finish ();});}

Here we use several operators: first, mergeDelayError, which means to merge several different Observable; sample means to sample at intervals of time, obtain the last published Observable within the interval. flatMap converts an Observable to another Observable.

As you can see, with RxJava, the entire code is very clear, so you don't have to consider the underlying thread synchronization, asynchronous notifications, and other content, and focus on how to implement the business, this is the charm of responsive function programming!

Operator Classification

Through the example above, we can see the power of RxJava operators. Next I will introduce common operators by category. In fact, many of the content is from ReactiveX's official website, good English friends can refer to (http://reactivex.io /).
According to the official classification, operators are roughly divided into the following types:

Creating Observables (the creation operator of Observable), such as: Observable. create (), Observable. just (), Observable. from () and so on; Transforming Observables (Conversion operator of Observable), for example: observable. map (), observable. flatMap (), observable. buffer () and so on; Filtering Observables (filter operator of Observable), for example: observable. filter (), observable. sample (), observable. take () and so on; Combining Observables (composite operator of Observable), for example: observable. join (), observable. merge (), observable. combineLatest () and so on; Error Handling Operators (Observable Error Handling operator), such as: observable. onErrorResumeNext (), observable. retry () and so on; Observable Utility Operators (functional Operators of Observable), such as: observable. subscribeOn (), observable. observeOn (), observable. delay () and so on; Conditional and Boolean Operators (Conditional Operators of Observable), such as: observable. amb (), observable. contains (), observable. skipUntil () and so on; Mathematical and Aggregate Operators (Observable Mathematical operations and Aggregate Operators), such as: observable. count (), observable. reduce (), observable. concat () and so on; others such as observable. toList (), observable. connect (), observable. publish () and so on; create Operator

The create operator is the "root" of all created operators. That is to say, other created operators use the create operator to create the Observable. The flowchart is as follows:

The call example is as follows: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwcmUgY2xhc3M9 "brush: java;"> Observable.create(new Observable.OnSubscribe () { @Override public void call(Subscriber observer) { try { if (!observer.isUnsubscribed()) { for (int i = 1; i < 5; i++) { observer.onNext(i); } observer.onCompleted(); } } catch (Exception e) { observer.onError(e); } } } ).subscribe(new Subscriber () { @Override public void onNext(Integer item) { System.out.println("Next: " + item); } @Override public void onError(Throwable error) { System.err.println("Error: " + error.getMessage()); } @Override public void onCompleted() { System.out.println("Sequence complete."); } });

The running result is as follows:
Next: 1
Next: 2
Next: 3
Next: 4
Sequence complete.

When using the create operator, it is best to add the isUnsubscribed judgment to the callback call function so that the subscriber will no longer execute the relevant code logic in the call function when canceling the subscription, this avoids unexpected errors;

From Operator

The from operator converts objects and Data Types of other types to Observable. The flowchart is as follows:

The call example is as follows:

Integer[] items = { 0, 1, 2, 3, 4, 5 };Observable myObservable = Observable.from(items);myObservable.subscribe(    new Action1
  
   () {        @Override        public void call(Integer item) {            System.out.println(item);        }    },    new Action1
   
    () {        @Override        public void call(Throwable error) {            System.out.println("Error encountered: " + error.getMessage());        }    },    new Action0() {        @Override        public void call() {            System.out.println("Sequence complete");        }    });
   
  

The running result is as follows:
0
1
2
3
4
5
Sequence complete

Just Operator

The just operator converts other types of objects and data to Observable. It is similar to the from operator, but the parameters of the method are different. The flowchart is as follows:

The call example is as follows:

Observable.just(1, 2, 3)          .subscribe(new Subscriber
  
   () {        @Override        public void onNext(Integer item) {            System.out.println("Next: " + item);        }        @Override        public void onError(Throwable error) {            System.err.println("Error: " + error.getMessage());        }        @Override        public void onCompleted() {            System.out.println("Sequence complete.");        }    });
  

The running result is as follows:
Next: 1
Next: 2
Next: 3
Sequence complete.

Defer Operator

The defer operator creates and executes the Observable through the factory method of the Observable only when a subscriber subscribes. The defer operator ensures that the Observable status is the latest. Its Process example is as follows:

The following compares the running results of the defer and just operators:

        i=10;        Observable justObservable = Observable.just(i);        i=12;        Observable deferObservable = Observable.defer(new Func0
  
   >() {            @Override            public Observable
    call() {                return Observable.just(i);            }        });        i=15;        justObservable.subscribe(new Subscriber() {            @Override            public void onCompleted() {            }            @Override            public void onError(Throwable e) {            }            @Override            public void onNext(Object o) {                System.out.println("just result:" + o.toString());            }        });        deferObservable.subscribe(new Subscriber() {            @Override            public void onCompleted() {            }            @Override            public void onError(Throwable e) {            }            @Override            public void onNext(Object o) {                System.out.println("defer result:" + o.toString());            }        });   }
  

Where I is a member variable of the class, the running result is as follows:
Just result: 10
Defer result: 15

As you can see, the just operator performs the value assignment operation when the Observable is created, and the defer operator creates the Observable only when the subscriber subscribes.

Timer Operator

The timer operator is used to create a series of consecutive numbers. The time interval between these numbers is certain. There are two cases:

One is to generate a number after a period of time, and then end. It can be understood as a delay to generate a number. The process example is as follows:
One is to generate a number at intervals without an Terminator, that is, an infinite number can be generated. The process example is as follows:

By default, the timer operator runs on a new thread. Of course, you can pass in parameters to modify the running thread.
The following is a call example:

// Generate an Observable. timer (2, 2, TimeUnit. SECONDS). subscribe (new Subscriber
  
   
() {@ Override public void onCompleted () {System. out. println ("Sequence complete. ") ;}@ Override public void onError (Throwable e) {System. out. println ("error:" + e. getMessage () ;}@ Override public void onNext (Long aLong) {System. out. println ("Next:" + aLong. toString ());}});
  

The running result is as follows:
Next: 0
Next: 1
Next: 2
Next: 3
......

Interval Operator

The interval operator generates a number every time. These numbers start from 0 and increase by 1 at a time until infinity. The implementation of the interval operator is the same as that of the following timer operator. The following is a process example:

The interval operator runs on a new thread by default. Of course, you can pass in parameters to modify the running thread.

The call examples are not listed, basically the same as the above timer call examples.

Range Operator

The range operator creates a set of continuous numbers starting from n with m. For example, range () is used to create 3, 4, 5... 12. The process example is as follows:

The call example is as follows:

// Generate a continuous number of 10 from 3. range (). subscribe (new Subscriber
  
   
() {@ Override public void onCompleted () {System. out. println ("Sequence complete. ") ;}@ Override public void onError (Throwable e) {System. out. println ("error:" + e. getMessage () ;}@ Override public void onNext (Integer I) {System. out. println ("Next:" + I. toString ());}});
  

The running result is as follows:
Next: 3
Next: 4
Next: 5
Next: 6
....
Next: 12
Sequence complete.

Repeat/repeatWhen Operator

The repeat operator is used to repeatedly generate results for an Observable. The process example is as follows:

The repeatWhen operator is a conditional re-subscription of an Observable to generate multiple results. The process example is as follows:

The repeat and repeatWhen operators run on a new thread by default. Of course, you can pass in parameters to modify the running thread.

The repeat call example is as follows:

// Generate two consecutive groups of numbers (3, 4, 5), Observable. range (3, 3). repeat (2). subscribe (new Subscriber
  
   
() {@ Override public void onCompleted () {System. out. println ("Sequence complete. ") ;}@ Override public void onError (Throwable e) {System. out. println ("error:" + e. getMessage () ;}@ Override public void onNext (Integer I) {System. out. println ("Next:" + I. toString ());}});
  

The running result is as follows:
Next: 3
Next: 4
Next: 5
Next: 3
Next: 4
Next: 5
Sequence complete.

Now, this article will continue to introduce other operators of RxJava, so stay tuned!

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.