RxJava journey from scratch (2) ---- RxJava operator

Keywords: Lambda less Windows

This article only parses operators in standard packs.For expansion packs, due to low usage, readers should consult the documentation for their own needs.

Create Operation

The following operators are used to create Observable.

  • Create: It is easier to create an Observable from scratch using OnSubscribe.It is important to note that when created using this method, it is recommended that the subscription status be checked in the OnSubscribe#call method to stop sending data or operations in time.
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                //Do some other things
                //.............
                //Execution complete, trigger callback, notify observer
                e.onNext("Let me send data");
            }
        });
  • From: Converts an Iterable, a Future, or an array internally into an Observable by proxy.The conversion from Future to OnSubscribe is done through OnSubscribeToObservableFuture, and the conversion from Iterable to OnSubscribeFromIterable.Arrays are converted via OnSubscribeFromArray.

  //Iterable
    List<String> list=new ArrayList<>();
    ...
    Observable.from(list)
            .subscribe(new Action1<String>() {
        @Override
        public void call(String s) {

        }
    });

    //Future
     Future<String> futrue= Executors.newSingleThreadExecutor().submit(new Callable<String>() {

        @Override
        public String call() throws Exception {
            Thread.sleep(1000);
            return "maplejaw";
        }
    });

    Observable.from(futrue)
              .subscribe(new Action1<String>() {
        @Override
        public void call(String s) {

        }
    });
;
  • Just: Using just(), an Observable is created for you and automatically calls onNext() to send data for you.just() triggers onNext() directly, and the parameters passed in just are received directly in Observer's onNext() method.
Observable<String> observable = Observable.just("Hello");
  • empty: Create an Observable that does nothing and notifies you directly of the completion

  • Error: Create an Observable that does nothing to notify the error directly

  • Nev: Create an Observable that does nothing

    Observable observable1=Observable.empty();//Call onCompleted directly.
    Observable observable2=Observable.error(new RuntimeException());//Call onError directly.You can customize exceptions here
    Observable observable3=Observable.never();//Do nothing
  • timer: Creates an Observable that emits data item 0 after a given delay and works internally through OnSubscribeTimerOne
 Observable.timer(1000,TimeUnit.MILLISECONDS)
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                    Log.d("JG",aLong.toString()); // 0
                }
            });
  • Interval: Creates an Observable that emits a zero-based sequence of integers at a given interval and works internally through OnSubscribeTimerPeriodically.
 Observable.interval(1, TimeUnit.SECONDS)
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                     //every other1Seconds to send data items from0Start Count
                     //0,1,2,3....
                }
            });
  • Range: Creates an Observable that transmits an integer sequence of a specified range
 Observable.range(2,5).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer integer) {
            Log.d("JG",integer.toString());// 2,3,4,5,6 Launch 5 data from 2
        }
    });
  • defer: Observable is created only when subscribers subscribe, creating a new Observable for each subscription.Internally create Observable by calling Func0 at subscription time through OnSubscribeDefer.
  Observable.defer(new Func0<Observable<String>>() {
        @Override
        public Observable<String> call() {
            return Observable.just("hello");
        }
    }).subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
            Log.d("JG",s);
        }
    });

Merge operation

The following operators are used to combine multiple Observable s.

Note that to make the structure clearer and to reduce the amount of code, the following examples will be written in part using Lambda expressions, which you can read if you are not familiar with Complete parsing of JAVA8 Lambda expression This article.

  • Concat: Connect multiple Observables sequentially.It is important to note that Observable.concat(a,b) is equivalent to a.concatWith(b).
    Observable<Integer> observable1=Observable.just(1,2,3,4);
    Observable<Integer>  observable2=Observable.just(4,5,6);

    Observable.concat(observable1,observable2)
            .subscribe(item->Log.d("JG",item.toString()));//1,2,3,4,4,5,6
  • StartWith: Add a data item at the beginning of the data series.Conat is also called inside startWith
 Observable.just(1,2,3,4,5)
            .startWith(6,7,8)
    .subscribe(item->Log.d("JG",item.toString()));//6,7,8,1,2,3,4,5
  • merge: merge multiple Observables into one.Unlike concat, merges are not connected in the order they were added, but in a timeline.mergeDelayError delays the exception until the other error-free Observables have been sent.merge, on the other hand, stops sending data when it encounters an exception and sends an onError notification.

  • zip: Combine multiple sets of data emitted by Observables using a single function, and then emit the result.If multiple Observables emit different amounts of data, the minimum Observables are used as the criterion for compression.Internal compression occurs through OperatorZip.
Observable<Integer>  observable1=Observable.just(1,2,3,4);
Observable<Integer>  observable2=Observable.just(4,5,6);


    Observable.zip(observable1, observable2, new Func2<Integer, Integer, String>() {
        @Override
        public String call(Integer item1, Integer item2) {
            return item1+"and"+item2;
        }
    })
    .subscribe(item->Log.d("JG",item)); //1and4,2and5,3and6

zip workflow

  • CombineLatest:.When either of the two Observables emits one data, the latest data (two data in total) emitted by each Observable is combined through a specified function, and the results of this function are emitted.Similar to zip, however, the difference is that zip only works if each Observable emits data, whereas combineLatest any emitted data can work, each time coinciding with the most recent data from another Observable.See the flowchart below for details.

combineLatest workflow

Filter operation

  • filter: filter the data.Internally, data is filtered through OnSubscribeFilter.
  Observable.just(3,4,5,6)
            .filter(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer>4;
                }
            })
    .subscribe(item->Log.d("JG",item.toString())); //5,6 
  • ofType: Filters data of a specified type, similar to a filter,
Observable.just(1,2,"3")
            .ofType(Integer.class)
            .subscribe(item -> Log.d("JG",item.toString()));
  • take: Only the starting N items of data or data for a certain period of time are sent.Internally, data is filtered through OperatorTake and OperatorTakeTimed.
  Observable.just(3,4,5,6)
            .take(3)//Three data items before launch
            .take(100, TimeUnit.MILLISECONDS)//launch100ms Data within
  • TakeLast: Only the last N items or a certain amount of data will be sent.Internally, data is filtered through Operator TakeLast and Operator TakeLastTimed.takeLastBuffer is similar to takeLast, except that it is collected into a List and emitted.
 Observable.just(3,4,5,6)
            .takeLast(3)
            .subscribe(integer -> Log.d("JG",integer.toString()));//4,5,6
  • takeFirst: Extract the first item that meets the criteria.The internal implementation source is as follows:
public final Observable<T> takeFirst(Func1<? super T, Boolean> predicate) {
      return filter(predicate).take(1); //Filter before extract
}
  • first/firstOrDefault: Only the first item (or the first item that satisfies a condition) of data is sent, and a default value can be specified.
 Observable.just(3,4,5,6)
            .first()
            .subscribe(integer -> Log.d("JG",integer.toString()));//3

    Observable.just(3,4,5,6)
               .first(new Func1<Integer, Boolean>() {
                   @Override
                   public Boolean call(Integer integer) {
                       return integer>3;
                   }
               }) .subscribe(integer -> Log.d("JG",integer.toString()));//4
  • last/lastOrDefault: Only the last item (or last item that satisfies a condition) of data is sent, and a default value can be specified.

  • skip: skip the starting N items or data over a period of time.Internal filtering is achieved through Operator skip and Operator SkipTimed.

  Observable.just(3,4,5,6)
               .skip(1)
            .subscribe(integer -> Log.d("JG",integer.toString()));//4,5,6
  • SkpLast: Skip the last N items or data for a certain period of time.Internal filtering is achieved through Operator skipLast and Operator SkipLastTimed.

  • elementAt/elementAtOrDefault: Launches a data item beyond the specified default value.Internal filters through Operator ElementAts.

        Observable.just(3,4,5,6)
                 .elementAt(2)
        .subscribe(item->Log.d("JG",item.toString())); //5
  • ignoreElements: Discard all data and only send an error or normal termination notification.Internally implemented through Operator ignoreElements.

  • distinct: Filters duplicate data, internally through Operator distinct.

 Observable.just(3,4,5,6,3,3,4,9)
       .distinct()
      .subscribe(item->Log.d("JG",item.toString())); //3,4,5,6,9
  • Distinct UntilChanged: Filters out continuously repeated data.Internal via Operator distinctUntilChanged
 Observable.just(3,4,5,6,3,3,4,9)
       .distinctUntilChanged()
      .subscribe(item->Log.d("JG",item.toString())); //3,4,5,6,3,4,9
  • throttleFirst: The first data sent by Observable is periodically transmitted.Internally implemented through Operator throttleFirst.
Observable.create(subscriber -> {
        subscriber.onNext(1);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(2);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }

        subscriber.onNext(3);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(4);
        subscriber.onNext(5);
        subscriber.onCompleted();

    }).throttleFirst(999, TimeUnit.MILLISECONDS)
            .subscribe(item-> Log.d("JG",item.toString())); //The result is 1,3,4
  • throttleWithTimeout/debounce: When data is transmitted, if the interval between two data launches is less than the specified time, the previous data is discarded until no new data is released within the specified time
Observable.create(subscriber -> {
        subscriber.onNext(1);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(2);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }

        subscriber.onNext(3);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(4);
        subscriber.onNext(5);
        subscriber.onCompleted();

    }).debounce(999, TimeUnit.MILLISECONDS)//Or throttleWithTimeout(1000, TimeUnit.MILLISECONDS)
            .subscribe(item-> Log.d("JG",item.toString())); //The result is 3,5
  • sample/throttleLast: Recent Observable data is periodically sent.Internally implemented through Operator SampleWithTime.
 Observable.create(subscriber -> {
        subscriber.onNext(1);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(2);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }

        subscriber.onNext(3);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(4);
        subscriber.onNext(5);
        subscriber.onCompleted();

    }).sample(999, TimeUnit.MILLISECONDS)//Or throttleLast(1000, TimeUnit.MILLISECONDS)
            .subscribe(item-> Log.d("JG",item.toString())); //The result is 2,3,5
  • timeout: If the original Observable has not emitted any data for a specified period of time, an exception is emitted or an alternate Observable is used.
  Observable.create(( subscriber) -> {
        subscriber.onNext(1);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(2);

        subscriber.onCompleted();

    }).timeout(999, TimeUnit.MILLISECONDS,Observable.just(99,100))//If no backup is specifiedObservableAn exception will be thrown
            .subscribe(item-> Log.d("JG",item.toString()),error->Log.d("JG","onError")); //The result is 1,99,100 if no backup is specifiedObservableResult 1,onError
}

Conditional/Boolean operation

  • All: Determines whether all data items satisfy a condition, internally through OperatorAll.
  Observable.just(2,3,4,5)
            .all(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer>3;
                }
            })
    .subscribe(new Action1<Boolean>() {
        @Override
        public void call(Boolean aBoolean) {
            Log.d("JG",aBoolean.toString()); //false
        }
    })
    ;
  • exists: Determines whether a data item satisfies a condition.Internally implemented through OperatorAny.
   Observable.just(2,3,4,5)
            .exists(integer -> integer>3)
            .subscribe(aBoolean -> Log.d("JG",aBoolean.toString())); //true
  • contains: Determines whether all data items emitted contain the specified data, and the internal call is actually exists
  Observable.just(2,3,4,5)
            .contains(3)
            .subscribe(aBoolean -> Log.d("JG",aBoolean.toString())); //true
  • sequenceEqual: Used to determine whether two Observable s emit the same data (data, transmission order, termination state).
 Observable.sequenceEqual(Observable.just(2,3,4,5),Observable.just(2,3,4,5))
            .subscribe(aBoolean -> Log.d("JG",aBoolean.toString()));//true
  • isEmpty: Used to determine if the Observable has sent data when it is finished.There is data false, true if only onComplete notifications are received.
  Observable.just(3,4,5,6)
               .isEmpty()
              .subscribe(item -> Log.d("JG",item.toString()));//false
  • amb: Given more than one Observable, only the Observable that first transmits data transmits all data, and the other Observables will be ignored.
    Observable<Integer> observable1=Observable.create(new Observable.OnSubscribe<Integer>() {
        @Override
        public void call(Subscriber<? super Integer> subscriber) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                subscriber.onError(e);
            }
            subscriber.onNext(1);
            subscriber.onNext(2);
            subscriber.onCompleted();
        }
    }).subscribeOn(Schedulers.computation());

    Observable<Integer> observable2=Observable.create(subscriber -> {
        subscriber.onNext(3);
        subscriber.onNext(4);
        subscriber.onCompleted();
    });

    Observable.amb(observable1,observable2)
    .subscribe(integer -> Log.d("JG",integer.toString())); //3,4
  • switchIfEmpty: If the original Observable terminates normally and no data is sent, use an alternate Observable.
   Observable.empty()
            .switchIfEmpty(Observable.just(2,3,4))
    .subscribe(o -> Log.d("JG",o.toString())); //2,3,4
  • defaultIfEmpty: If no data is sent after the original Observable terminates normally, a default value, switchIfEmpty called internally, is sent.

  • takeUntil: Terminates the first Observable from sending data when the transmitted data meets a certain condition (including the data) or when the second Observable is sent.

 Observable.just(2,3,4,5)
            .takeUntil(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer==4;
                }
            }).subscribe(integer -> Log.d("JG",integer.toString())); //2,3,4
  • takeWhile: Observable terminates sending data when the transmitted data meets a certain condition (excluding it).
  Observable.just(2,3,4,5)
            .takeWhile(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer==4;
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString())); //2,3
  • skipUntil: Discard data sent by Observable until the second Observable sends data.(discard conditional data)

  • skipWhile: Discard data emitted by Observable until a specified condition is not established (do not discard conditional data)

Aggregation Operation

  • Reduce: Use the reduce() function on the sequence and emit the final result, using OnSubscribeReduce internally.
  Observable.just(2,3,4,5)
            .reduce(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer sum, Integer item) {
                    return sum+item;
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString()));//14
  • Collect: Use collect to collect data to a variable data structure.
  Observable.just(3,4,5,6)
               .collect(new Func0<List<Integer>>() { //Create Data Structure

                   @Override
                   public List<Integer> call() {
                       return new ArrayList<Integer>();
                   }
               }, new Action2<List<Integer>, Integer>() { //collector
                   @Override
                   public void call(List<Integer> integers, Integer integer) {
                       integers.add(integer);
                   }
               })
              .subscribe(new Action1<List<Integer>>() {
                  @Override
                  public void call(List<Integer> integers) {

                  }
              });
  • count/countLong: Calculates the number of launches, internal call is reduce.

Conversion operation

  • toList: Collect all the data sent by the original Observable into a list and return to it.
    Observable.just(2,3,4,5)
            .toList()
            .subscribe(new Action1<List<Integer>>() {
                @Override
                public void call(List<Integer> integers) {

                }
            });
  • toSortedList: Collect all data emitted by the original Observable into an ordered list and return to it.
   Observable.just(6,2,3,4,5)
            .toSortedList(new Func2<Integer, Integer, Integer>() {//Custom Sorting
                @Override
                public Integer call(Integer integer, Integer integer2) {
                    return integer-integer2; //>0 ascending, <0 descending
                }
            })
            .subscribe(new Action1<List<Integer>>() {
                @Override
                public void call(List<Integer> integers) {
                    Log.d("JG",integers.toString()); // [2, 3, 4, 5, 6]
                }
            });
  • toMap: Converts sequence data into a Map.We can generate key s and value s from data items.
    Observable.just(6,2,3,4,5)
            .toMap(new Func1<Integer, String>() {
                @Override
                public String call(Integer integer) {
                    return "key: " + integer; //Generate key for map from data item
                }
            }, new Func1<Integer, String>() {
                @Override
                public String call(Integer integer) {
                    return "value: "+integer; //Generating kvalue of map from data item
                }
            }).subscribe(new Action1<Map<String, String>>() {
        @Override
        public void call(Map<String, String> stringStringMap) {
            Log.d("JG",stringStringMap.toString()); // {key: 6=value: 6, key: 5=value: 5, key: 4=value: 4, key: 2=value: 2, key: 3=value: 3}
        }
    });
  • toMultiMap: Similar to toMap, the difference is that the value of a map is a collection.

Transform operation

  • map: A function is applied to each data sent by Observable to transform it.
 Observable.just(6,2,3,4,5)
            .map(integer -> "item:"+integer)
            .subscribe(s -> Log.d("JG",s));//item:6,item:2....
  • cast: Forces all data sent by Observable to be converted to the specified type before it is sent
       Observable.just(2,3,5)
            .flatMap(new Func1<Integer, Observable<String>>() {
                @Override
                public Observable<String> call(Integer integer) {
                    return Observable.create(subscriber -> {
                        subscriber.onNext(integer*10+"");
                        subscriber.onNext(integer*100+"");
                        subscriber.onCompleted();
                    });
                }
            })
    .subscribe(o -> Log.d("JG",o)) //20,200,30,300,50,500
  • flatMap: Transform Observable-emitted data into Observables collection, then flatten the Observable-emitted data into a single Observable with merge inside.
       Observable.just(2,3,5)
            .flatMap(new Func1<Integer, Observable<String>>() {
                @Override
                public Observable<String> call(Integer integer) {
                    return Observable.create(subscriber -> {
                        subscriber.onNext(integer*10+"");
                        subscriber.onNext(integer*100+"");
                        subscriber.onCompleted();
                    });
                }
            })
    .subscribe(o -> Log.d("JG",o)) //20,200,30,300,50,500
  • flatMapIterable: Like flatMap, it just generates an Iterable instead of an Observable.
        Observable.just(2,3,5)
            .flatMapIterable(new Func1<Integer, Iterable<String>>() {
                @Override
                public Iterable<String> call(Integer integer) {
                    return Arrays.asList(integer*10+"",integer*100+"");
                }
            }).subscribe(new Action1<String>() {
              @Override
              public void call(String s) {

              }
    });
  • concatMap: Similar to flatMap, because concat merge is used internally, it is launched sequentially.

  • switchMap: Similar to flatMap, it transforms the data emitted by Observable into an Observables collection, and when the original Observable emits a new data (Observable), it cancels the previous Observable subscription.

  Observable.create(new Observable.OnSubscribe<Integer>() {

        @Override
        public void call(Subscriber<? super Integer> subscriber) {
            for(int i=1;i<4;i++){
                subscriber.onNext(i);
                Utils.sleep(500,subscriber);//Thread sleeps 500ms
            }

            subscriber.onCompleted();
        }
    }).subscribeOn(Schedulers.newThread())
      .switchMap(new Func1<Integer, Observable<Integer>>() {
             @Override
           public Observable<Integer> call(Integer integer) {
                   //The previous Observable will be unsubscribed whenever new data is received
                    return Observable.create(new Observable.OnSubscribe<Integer>() {
                        @Override
                        public void call(Subscriber<? super Integer> subscriber) {
                            subscriber.onNext(integer*10);
                            Utils.sleep(500,subscriber);
                            subscriber.onNext(integer*100);
                            subscriber.onCompleted();
                        }
                    }).subscribeOn(Schedulers.newThread());
                }
            })
            .subscribe(s -> Log.d("JG",s.toString()));//10,20,30,300


  • scan: Similar to reduce, a function is applied to each data emitted by Observable, and each value is emitted sequentially.
  Observable.just(2,3,5)
            .scan(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer sum, Integer item) {
                    return sum+item;
                }
            })
    .subscribe(integer -> Log.d("JG",integer.toString())) //2,5,10
  • groupBy: Split Observables into Observables collections, group data sent by the original Observables into Key s, and each Observable emits a different set of data.
   Observable.just(2,3,5,6)
            .groupBy(new Func1<Integer, String>() {
                @Override
                public String call(Integer integer) {//Grouping
                    return integer%2==0?"Even numbers":"Odd Number";
                }
            })
    .subscribe(new Action1<GroupedObservable<String, Integer>>() {
        @Override
        public void call(GroupedObservable<String, Integer> o) {

            o.subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    Log.d("JG",o.getKey()+":"+integer.toString()); //Even number: 2, odd number: 3,...
                }
            });
        }
    })
  • buffer: It periodically collects data from Observable to a collection and then packages these data collections for launch instead of one at a time
    Observable.just(2,3,5,6)
            .buffer(3)
            .subscribe(new Action1<List<Integer>>() {
                @Override
                public void call(List<Integer> integers) {

                }
            })
  • window: Periodically break data from Observable into Observable windows and launch them instead of one at a time.
   Observable.just(2,3,5,6)
            .window(3)
            .subscribe(new Action1<Observable<Integer>>() {
                @Override
                public void call(Observable<Integer> integerObservable) {
                    integerObservable.subscribe(new Action1<Integer>() {
                        @Override
                        public void call(Integer integer) {

                        }
                    });
                }
            })

Error handling/retry mechanism

  • onErrorResumeNext: Use alternate Observable when the original Observable encounters errors.
  Observable.just(1,"2",3)
    .cast(Integer.class)
    .onErrorResumeNext(Observable.just(1,2,3))
    .subscribe(integer -> Log.d("JG",integer.toString())) //1,2,3
    ;
  • OnExceptionResumeNext: Use an alternate Observable when the original Observable encounters an exception.Similar to onErrorResumeNext, the difference is that onErrorResumeNext handles all errors, and onExceptionResumeNext handles only exceptions.

  • onErrorReturn: When the original Observable encounters an error, it emits a specific data.

 Observable.just(1,"2",3)
            .cast(Integer.class)
            .onErrorReturn(new Func1<Throwable, Integer>() {
                @Override
                public Integer call(Throwable throwable) {
                    return 4;
                }
            }).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer integer) {
            Log.d("JG",integer.toString());1,4
        }
    });
  • retry: retry when the original Observable encounters an error.
    Observable.just(1,"2",3)
    .cast(Integer.class)
    .retry(3)
    .subscribe(integer -> Log.d("JG",integer.toString()),throwable -> Log.d("JG","onError"))
    ;//1,1,1,1,onError
  • retryWhen: When the original Observable encounters an error and passes it to another Observable to decide whether to re-subscribe to the Observable, retry is invoked internally.
  Observable.just(1,"2",3)
    .cast(Integer.class)
    .retryWhen(new Func1<Observable<? extends Throwable>, Observable<Long>>() {
        @Override
        public Observable<Long> call(Observable<? extends Throwable> observable) {
            return Observable.timer(1, TimeUnit.SECONDS);
        }
    })
    .subscribe(integer -> Log.d("JG",integer.toString()),throwable -> Log.d("JG","onError"));
    //1,1

Connection operation

ConnectableObservable is similar to a regular Observable, but a connectable Observable does not start sending data when it is subscribed to, but only when its connect() is called.In this way, you can wait until all potential subscribers have subscribed to the Observable before you start sending data.

ConnectableObservable.connect() indicates that a connectable Observable starts sending data.

Observable.publish() converts an Observable to a connectable Observable

Observable.replay() ensures that all subscribers see ConnectableObservable with the same data sequence, even if they do not subscribe until Observable starts sending data.

ConnectableObservable.refCount() allows a connectable Observable to behave like a normal Observable.

       ConnectableObservable<Integer> co= Observable.just(1,2,3)
                .publish();

        co .subscribe(integer -> Log.d("JG",integer.toString()) );
        co.connect();//Start sending data at this time

Blocking operation

BlockingObservable is a blocked Observable.Ordinary Observables are converted to BlockingObservable using either the Observable.toBlocking() method or the BlockingObservable.from() method.The blocking operation is internally implemented through CountDownLatch.

The following operators can be used for BlockingObservable. If you are a regular Observable, be sure to use Observable.toBlocking() after blocking Observable, otherwise you will not achieve the desired effect.

  • forEach: Calling a method on each data sent by BlockingObservable will block until Observable completes.
Observable.just(2,3).observeOn(Schedulers.newThread()).toBlocking()
          .forEach(integer -> {
              Log.d("JG",integer.toString()+" "+Thread.currentThread().getName());
              Utils.sleep(500);
          });

Log.d("JG",Thread.currentThread().getName());
    // 2 RxNewThreadScheduler-1
    // 3 RxNewThreadScheduler-1
    // main
  • first/firstOrDefault/last/lastOrDefault: These operators were described earlier.It can also be used for blocking operations.

  • single/singleOrDefault: If only one value is emitted when Observable terminates, return that value, otherwise throw an exception or emit a default value.

  • mostRecent: Returns an Iterable that always returns the most recently emitted data from Observable.

  • next: Returns an Iterable, blocking until Observable emits a second value, then returns that value.

  • latest: Returns an iterable, which will block until or unless Observable sends a value that Iterable does not return, and then returns that value

  • toFuture: Convert Observable to a Future

  • toIterable: Converts an Observable of a transmitted data sequence to an Iterable.

  • getIterator: Converts an Observable of a transmitted data sequence to an Iterator

Toolset

  • materialize: Converts Observable to a notification list.
 Observable.just(1,2,3)
           .materialize()
           .subscribe(new Action1<Notification<Integer>>() {
               @Override
               public void call(Notification<Integer> notification) {
                   Log.d("JG",notification.getKind()+" "+notification.getValue());
                   //OnNext 1
                   //OnNext 2
                   //OnNext 3
                   //OnCompleted null
               }
           });
  • dematerialize: Reverses the notification back to an Observable, as opposed to the above.

  • Timestamp: Add a timestamp to each data item that Observable emits.

  Observable.just(1,2,3)
           .timestamp()
           .subscribe(new Action1<Timestamped<Integer>>() {
               @Override
               public void call(Timestamped<Integer> timestamped) {
                   Log.d("JG",timestamped.getTimestampMillis()+" "+timestamped.getValue());
                   //1472627510548 1
                   //1472627510549 2
                   //1472627510549 3
               }
           });
  • timeInterval: Adds a time difference between two data items sent by Observable, implemented in Operator timeInterval

  • serialize: Force Observable to send data in order and require functionality to be good

  • cache: cache the data sequence sent by Observable and send the same data sequence to subsequent subscribers

  • observeOn: The scheduler that specifies the observer to observe Observable

  • subscribeOn: Specifies the scheduler for Observable to perform tasks

  • doOnEach: Register an action to use for each data item emitted by Observable

  Observable.just(2,3)
            .doOnEach(new Action1<Notification<? super Integer>>() {
                @Override
                public void call(Notification<? super Integer> notification) {
                    Log.d("JG","--doOnEach--"+notification.toString());
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString()));
//The results are:            
 // --doOnEach--[rx.Notification@133c40b0 OnNext 2]
// 2
 // --doOnEach--[rx.Notification@133c40b0 OnNext 3]
// 3
// --doOnEach--[rx.Notification@df4db0e OnCompleted]
  • doOnCompleted: Register an action to use for normally completed Observable s

  • doOnError: Register an action to use with the Observable where the error occurred

  • doOnTerminate: Register an action to use for the completed Observable, whether an error occurs or not

  Observable.just(2,3)
            .doOnTerminate(new Action0() {
                @Override
                public void call() {
                    Log.d("JG","--doOnTerminate--");
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString()));
// 2 , 3 , --doOnTerminate--
  • doOnSubscribe: Registers an action to be used when an observer subscribes.Internally implemented by Operator doOnSubscribe,

  • doOnUnsubscribe: Registers an action to be used when an observer unsubscribes.Internally implemented by OperatorDoOnUnsubscribe, an unbind action is added to the call.

  • finallyDo/doAfterTerminate: Register an action to use when Observable is complete
Observable.just(2,3)
            .doAfterTerminate(new Action0() {
                @Override
                public void call() {
                    Log.d("JG","--doAfterTerminate--");
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString()));
//2,3,  --doAfterTerminate-- 
  • delay: delay the result of the Observable.That is, the original Observable is paused for a specified period of time before each data is sent.The effect is that the data item emitted by Observable moves forward an increment in time as a whole (with the exception of onError, which is notified immediately).

  • delaySubscription: Delays processing subscription requests.Implemented in OnSubscribeDelaySubscription

  • using: Create a resource that exists only in the Observable lifecycle and is automatically released when the Observable terminates.
  Observable.using(new Func0<File>() {//Resource Factory
        @Override
        public File call() {

            File file = new File(getCacheDir(), "a.txt");
            if(!file.exists()){
                try {
                    Log.d("JG","--create--");
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return file;
        }
    }, new Func1<File, Observable<String>>() { //Observable
        @Override
        public Observable<String> call(File file) {
            return Observable.just(file.exists() ? "exist" : "no exist");
        }
    }, new Action1<File>() {//Release Resource Action
        @Override
        public void call(File file) {
            if(file!=null&&file.exists()){
                Log.d("JG","--delete--");
                file.delete();
            }
        }
    })
    .subscribe(s -> Log.d("JG",s))
    ;
 //--create--
 //exist
 //--delete--
  • single/singleOrDefault: Forces a single data to be returned, otherwise an exception or default data is thrown.

Last

Operators for the RxJava Standard Library have been described, purely as a memo.If there are any errors, please point them out.

For reprinting, please indicate the source: http://blog.csdn.net/maplejaw_/article/details/52396175

Posted by scald on Mon, 03 Jun 2019 20:38:03 -0700