RxJava Quick Start

Posted by sbarros on Sat, 22 Jun 2019 20:03:02 +0200

Preface

I believe that you have heard about RxJava for a long time, so I will not repeat what RxJava is, you can Baidu yourself if you don't know it.If you already have a general idea of what RxJava is and want to start learning, then this article is a good choice for you. Why do you say so, because I have only been learning for a few days, which is called "Know who you are, fight for nothing".RxJava has a high threshold for getting started on the Internet, but after these days of learning, I don't think so. I dare not say that I am proficient, but it's really not difficult to get started, don't believe it?Let me start with a simple example to preheat.

Create a data transmission source first, which is understandable for transmitting data:

   Observable<String> sender = Observable.create(new Observable.OnSubscribe<String>() {

           @Override
            public void call(Subscriber<? super String> subscriber) {

                subscriber.onNext("Hi,Weavey!");  //Send data "Hi, Weavey!"
            }
        });

Create another data receiving source, similarly, for receiving data:

   Observer<String> receiver = new Observer<String>() {

            @Override
            public void onCompleted() {

                //Called when data reception is complete
            }

            @Override
            public void onError(Throwable e) {

                //Error call occurred
            }

            @Override
            public void onNext(String s) {

               //Normal Receive Data Calls
                System.out.print(s);  //You'll receive a greeting from sender, "Hi, Weavey!"
            }
        };

Okay, associate the transmit source with the receive source:

  sender.subscribe(receiver);

This results in a simple use of RxJava, where sender emits "Hi, Weavey!"", will be accepted by receiver's onNext. In this case, you might think of"asynchronous","observer mode". Yes, these are all things RxJava does, and they make them simpler and simpler. All of RxJava will be around these two points: sending data and receiving data. Is that easy to understand?If you understand this or you already know that RxJava is such a thing, congratulations, you've stepped into the door of RxJava with one foot, if not!!!!That doesn't matter. Keep looking down...

On the Importance of Concepts

There are also many blogs about RxJava on the Internet, and I have read a lot of them, including excellent articles, but most of them have one thing in common: they focus on the various powerful operators in RxJava, while ignoring the most basic thing - concept, so at first I looked confused, and forgot the front when I saw it, and my mind was full of question marks. This isWhat, what is that, how do these two look like?To give an inappropriate example, the concept is for beginners, just like food for people. When you are hungry, you will want to eat bread and milk. Why don't you eat dirt? Because you know what bread and milk are for and what soil is for.Likewise, as I have said before, RxJava is nothing more than sending and receiving data, so what is the launch source and what is the receive source. This is what you should be clear about and one of the starting conditions for RxJava. Below is my personal understanding of how to classify the launch and receive sources, as well as several "words" that occur frequently in RxJava, which can't be said well, please understand., welcome to add.

Basic concepts

Observable: Emission source, which means "observable" in English and is called "observable" or "observable object" in observer mode;

Observer: Receive source, English meaning "observer", right!It is the "observer" in the observer mode, which receives data sent by Observable and Subject.

Subject:Subject is a special object, which can act as both a source of transmission and a source of reception. In order to avoid confusion among beginners, this chapter will not make too much explanations and use of Subject, focus on Observable and Observer, first learn the use of the most basic methods, and then learn other problems.

Subscriber: "Subscriber" is also a source of reception, so what's the difference between it and Observer?Subscriber implements the Observer interface, which is one of the most important methods for unsubscribe() to cancel subscriptions. When you no longer want to receive data, you can call the unsubscribe() method to stop receiving. Observer will eventually be converted to a Subscriber object in the subscribe() process. Generally, Subscriber is recommended as the receiving source.

Subscription: Object returned by Observable calling subscribe() method, also unsubscribe() method, which can be used to unsubscribe events;

An interface in Action0:RxJava that has only one non-parametric call() method and no return value, as well as Action1, Action2, Action9, etc. Action1 encapsulates the call() method with 1 parameter, namely call (T), Action2 encapsulates the call method with 2 parameters, namely call (T1 t1, T2 t2), and so on;

Func0: Much like Action0, there is also a call () method, but it has a return value, as well as Func0, Func1...Func9;

Basic Usage

  • Creation of Observable
    1. Use create(), the most basic way to create:

    normalObservable = Observable.create(new Observable.OnSubscribe<String>() {
      @Override
      public void call(Subscriber<? super String> subscriber) {
          subscriber.onNext("create1"); //Launch a String for "create1"
          subscriber.onNext("create2"); //Launch a String for "create2"
          subscriber.onCompleted();//Launch complete, which requires manual onCompleted callback to Observer's onCompleted method
      }});

    2. Using just(), an Observable is created for you and automatically calls onNext() to send data for you:

    justObservable = Observable.just("just1","just2");//Send "just1" and "just2" in turn

    3. Use from(), traverse the collection, sending each item:

    List<String> list = new ArrayList<>();
    list.add("from1");
    list.add("from2");
    list.add("from3");
    fromObservable = Observable.from(list);  //Send one at a time through the list
    /** Be careful, just()Method can also be passed list,But it sent the whole list Object, and from()Sent is list Of item** /

    4. With defer(), Observable is created only when there is an observer subscription, and a new Observable is created for each observer:

    deferObservable = Observable.defer(new Func0<Observable<String>>() {
      @Override
      //Note that the call method here does not have a Subscriber parameter
      public Observable<String> call() {
          return Observable.just("deferObservable");
      }});

    5. Using interval(), create an Observable that transmits a sequence of integers at regular intervals, which can be used as a timer:

    intervalObservable = Observable.interval(1, TimeUnit.SECONDS);//Send every second

    6. Using range(), create an Observable that transmits a specific sequence of integers, with the first parameter as the starting value and the second as the number of sends. If 0 does not send, negative numbers throw an exception:

    rangeObservable = Observable.range(10, 5);//Integers 10, 11, 12, 13, 14 will be sent

    7. Using timer(), create an Observable that emits a special value after a given delay, equivalent to the postDelay() method of Handler in Android:

    timeObservable = Observable.timer(3, TimeUnit.SECONDS);  //Send a value after 3 seconds

    8. Using repeat(), create an Observable that repeatedly transmits specific data:

    repeatObservable = Observable.just("repeatObservable").repeat(3);//Re-launch 3 times
  • Creation of Observer

    mObserver = new Observer<String>() {
      @Override
      public void onCompleted() {
          LogUtil.log("onCompleted");
      }
      @Override
      public void onError(Throwable e) {
      }
      @Override
      public void onNext(String s) {
          LogUtil.log(s);
      }};

    ok, with Observable and Obsever, we can play around and pick one of the Observables and Observer associations that have been created to form an example of RxJava, such as:

    justObservable.subscribe(mObserver);

    The onNext method of mObserver will receive the data "just1", "just2" from justObservable in turn. In addition, if you do not care if the data has been received or if there is an error, that is, the onCompleted() and onError() methods of Observer are not needed, you can use Action1, subscribe() to support passing Action1 as a parameter, and RxJava will call its call method to receive data, such as code.Next:

    justObservable.subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
    
              LogUtil.log(s);
         }});

    These are the simplest uses of RxJava.Looking at this, I don't know if my writing is simple and clear either. Perhaps you would think, "Oops, how can I write an asynchronous thing? Why don't I use Thread+Handler"? Then you are wrong. RxJava is also loved by most users because of its simplicity. Simplicity cannot be interpreted as a small amount of code. However, with the complexity of logic and the change of requirements, the code can still be preserved.With a strong readability, let's take a simple example (high-energy alert in front of ~~), the leader asks me to find out all user data from the user table of the database. I write in RxJava without saying anything about what I want to do:

         Observable.create(new Observable.OnSubscribe<List<User>>() {
              @Override
              public void call(Subscriber<? super List<User>> subscriber) {
                  List<User> userList = null;
                  ···
                  //Get user table data from the database and assign it to userList
                  ···
                  subscriber.onNext(userList);
              }
          }).subscribe(new Action1<List<User>>() {
              @Override
              public void call(List<User> users) {
    
                  //Get a list of user information
              }
          });

    However, the leader suddenly does not want all users anymore. As long as the user named "Xiao Ming", OK, the leader is the largest, I will change (assuming the name is unique):

        Observable.create(new Observable.OnSubscribe<List<User>>() {
              @Override
              public void call(Subscriber<? super List<User>> subscriber) {
                  List<User> userList = null;
                  ···
                  //Get user table data from the database and assign it to userList
                  ···
                  subscriber.onNext(userList);
              }
          }).flatMap(new Func1<List<User>, Observable<User>>() {
              @Override
              public Observable<User> call(List<User> users) {
                  return Observable.from(users);
              }
          }).filter(new Func1<User, Boolean>() {
              @Override
              public Boolean call(User user) {
                  return user.getName().equals("Xiao Ming");
              }
          }).subscribe(new Action1<User>() {
              @Override
              public void call(User user) {
                  //Get the data for the puzzle Xiaoming
              }
          });

    Okay, then the leader said, I don't want to be clear, I want Xiao Ming's dad's data, (pit dad~~), I continue to change:

    Observable.create(new Observable.OnSubscribe<List<User>>() {
              @Override
              public void call(Subscriber<? super List<User>> subscriber) {
                  List<User> userList = null;
                  ···
                  //Get user table data from the database and assign it to userList
                  ···
                  subscriber.onNext(userList);
              } 
         }).flatMap(new Func1<List<User>, Observable<User>>() {
              @Override
              public Observable<User> call(List<User> users) {
                  return Observable.from(users);
              }
          }).filter(new Func1<User, Boolean>() {
              @Override
              public Boolean call(User user) {
                  return user.getName().equals("Xiao Ming");
              }
          }).map(new Func1<User, User>() {
              @Override
              public User call(User user) { 
                  //Find out Xiao Ming's father user2 from the database based on Xiao Ming's data user
                  return user2;
              }
          }).subscribe(new Action1<User>() {
              @Override
              public void call(User user2) {
                //Get the data for Xiao Ming's Dad
              }
          });

    Find out, "What else do you want to do?Leaders say @.
    In the above example, involving a few operators, beginners may not understand, but that's not the point. My purpose is to show you that RxJava can still keep the code simple and readable without callbacks or puzzle indentation, given the ever-changing demand and the ever-more complex logic!

 

Topics: Database Android