preface

  • RxjavaBecause of itsChain call based on event flow, simple logic & easy to useThe characteristics of the deepAndroidDeveloper welcome.


Making screenshots

If you are not familiar with RxJava, check out Android: a clear and easy-to-understand introduction to RxJava

  • RxJavaThat’s why it’s so popularProvides rich & powerful operators that can fulfill almost all functional requirements
  • Today, I will give you a detailed introductionRxJavaThe most commonly used of the operatorsFilter operatorI hope you like it.
  1. This series of articles is based onRxjava 2.0
  2. In the coming days, I will continue to publish a series of articles on Rxjava 2.0 in Android, including principles, operators, application scenarios, back pressure, etc. If you are interested, please continue to follow Carson_Ho’s Android development notes!!


Schematic diagram


directory


Schematic diagram


1. The role

Filter/filter events sent by observables & events received by observers


Type 2.

  • In RxJava2, the types of filter operators include:

    Schematic diagram

  • I’ll look at each operator in detail below

3. Description of application scenarios & Corresponding operators

  • The application scenarios of the filter operator include:
    1. Filter events based on specified conditions
    2. Filter events based on the specified number of events
    3. Filter events based on the specified time
    4. Filter events based on the specified event location
  • Next, I will explain the corresponding operators based on the above application scenarios

Note: Before using the RxJava 2 operator, remember to add dependencies to your project Gradle:

Dependencies {the compile 'IO. Reactivex. Rxjava2: rxandroid: 2.0.1' compile 'IO. Reactivex. Rxjava2: rxjava: 2.0.7' / / note: RxJava2 and RxJava1 cannot coexist, i.e. dependencies cannot exist at the same time}Copy the code

3.1 Filtering Events based on specified conditions

  • Requirement Scenario By setting specified filtering conditions, the event is filtered (not sent) if and only if the event meets the conditions.

  • Corresponding operator type


Schematic diagram

  • Use the corresponding operator

The Filter ()

  • Events that filter specific conditions

  • The principle of


Schematic diagram

  • The specific use
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { // 1. Sending 5 events emitters. OnNext (1); emitter.onNext(2); emitter.onNext(3); emitter.onNext(4); emitter.onNext(5); Filter (new Predicate<Integer>() {// Predicate events sent by the observer based on the return value of test() & // a. Return true, continue to send // b. Return false, @override public Boolean test(Integer Integer) throws Exception {return Integer > 3; Subscribe(new Observer<Integer>() {@override public void onSubscribe(Disposable) { Log.d(TAG, "Subscribe "); } @override public void onNext(Integer value) {log. d(TAG, "+ value); } @override public void onError(Throwable e) {log.d (TAG, "response to Error "); } @override public void onComplete() {log.d (TAG, "response to Complete event "); }});Copy the code
  • The test results


Schematic diagram

OfType ()

  • Function to filter data of a specific data type

  • The specific use

Observable.just(1, "Carson", 3, "Ho", Subscribe (new Consumer<Integer>() {@override public void accept(Integer). Subscribe (new Consumer<Integer>() {@override public void accept(Integer) Integer) throws Exception {log. d(TAG," fetch an integer event element: "+ INTEGER); }});Copy the code
  • The test results


Schematic diagram

Skip ()/skipLast ()

  • Function Skips an event

  • The specific use

// use 1: Observable. Just (1, 2, 3, 4, Subscribe (new Consumer<Integer>() {@override public void accept().subscribe(new Consumer<Integer>() {@override public void accept(); Integer Integer) throws Exception {log. d(TAG," the obtained Integer event element is: "+ Integer); }}); // Use 2: skip the data item according to the time // Send event features: send data 0-5, every 1s send once, each increment 1; 0s Observable. IntervalRange (0, 5, 0, 1, timeunit.seconds). Skip (1, timeunit.seconds) // Skip the data sent in 1s. Timeunit.seconds) // Skip the data sent in the last 1s. Subscribe (new Consumer<Long>() {@override public void accept(Long along) throws Exception {log. d(TAG," fetch event elements: "+ along); }});Copy the code
  • The test results


image.png

Distinct ()/distinctUntilChanged ()

  • Function Filters repeated events/consecutive repeated events in a sequence of events

  • The specific use

// use 1: Observable. Just (1, 2, 3, 1, 1) 2 ) .distinct() .subscribe(new Consumer<Integer>() { @Override public void accept( Integer integer) throws Exception { Log.d(TAG," non-repeating integer event elements are: "+ integer); }}); // use 2: // In the following sequence, DistinctUntilChanged ().subscribe(new Consumer<Integer>() {@override Public void Accept (Integer Integer) throws Exception {log. d(TAG," discontinuous and repeated Integer event elements are: "+ Integer); }});Copy the code
  • The test results


Schematic diagram


3.2 Filtering events based on the specified number of events

  • Requirement Scenarios Send only a specific number of events by setting a specified number of events

  • Corresponding operator types take () & takeLast ()

  • Use the corresponding operator

Take ()

  • Function Specifies the maximum number of events that an observer can receive

  • The principle of


Schematic diagram

  • The specific use
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { // 1. Sending 5 events emitters. OnNext (1); emitter.onNext(2); emitter.onNext(3); emitter.onNext(4); emitter.onNext(5); Take (2). Subscribe (new Observer<Integer>() {@override public void OnSubscribe (Disposable d) {Log. D (TAG, "subscribe "); } @override public void onNext(Integer value) {log. d(TAG, "+ value); } @override public void onError(Throwable e) {log.d (TAG, "response to Error "); } @override public void onComplete() {log.d (TAG, "response to Complete event "); }}); // The observer still sends 5 events, but because the operator intercepts 3 events, the observer receives 2 eventsCopy the code
  • The test results


Schematic diagram


TakeLast ()

  • Function Specifies that the observer will receive only the last few events sent by the observer

  • The specific use

Observable.just(1, 2, 3, 4, Subscribe(new Observer<Integer>() {@override public void onSubscribe(Disposable) D) {log. d(TAG, "subscribe "); } @override public void onNext(Integer value) {log. d(TAG, "+ value); } @override public void onError(Throwable e) {log.d (TAG, "response to Error "); } @override public void onComplete() {log.d (TAG, "response to Complete event "); }});Copy the code
  • The test results


Schematic diagram


3.3 Filtering Events based on the specified time

  • Requirement Scenario You can send only the events within the specified time

  • Corresponding operator type


Schematic diagram

  • Use the corresponding operator

ThrottleFirst ()/throttleLast ()

  • Function Sends only the first or last event within a period of time

For example, click a button consecutively for a period of time, but only click the button for the first time

  • Schematic diagram of principle


Schematic diagram

  • The specific use
<<- For a certain period of time, Observable. Create (new ObservableOnSubscribe<Integer>() {@override public void Subscribe (ObservableEmitter<Integer> e) throws Exception {subscribe(ObservableEmitter<Integer> e) throws Exception { Thread.sleep(500); e.onNext(2); Thread.sleep(400); e.onNext(3); Thread.sleep(300); e.onNext(4); Thread.sleep(300); e.onNext(5); Thread.sleep(300); e.onNext(6); Thread.sleep(400); e.onNext(7); Thread.sleep(300); e.onNext(8); Thread.sleep(300); e.onNext(9); Thread.sleep(300); e.onComplete(); } }).throttleFirst(1, Timeunit.seconds)// Subscribe(new Observer<Integer>() {@override public void onSubscribe(Disposable) { Log.d(TAG, "Subscribe "); } @override public void onNext(Integer value) {log. d(TAG, "received event "+ value); } @override public void onError(Throwable e) {log.d (TAG, "response to Error "); } @override public void onComplete() {log.d (TAG, "response to Complete event "); }}); <<- For a certain period of time, Observable. Create (new ObservableOnSubscribe<Integer>() {@override public void Subscribe (ObservableEmitter<Integer> e) throws Exception {subscribe(ObservableEmitter<Integer> e) throws Exception { Thread.sleep(500); e.onNext(2); Thread.sleep(400); e.onNext(3); Thread.sleep(300); e.onNext(4); Thread.sleep(300); e.onNext(5); Thread.sleep(300); e.onNext(6); Thread.sleep(400); e.onNext(7); Thread.sleep(300); e.onNext(8); Thread.sleep(300); e.onNext(9); Thread.sleep(300); e.onComplete(); } }).throttleLast(1, Timeunit.seconds)// Subscribe(new Observer<Integer>() {@override public void onSubscribe(Disposable) { Log.d(TAG, "Subscribe "); } @override public void onNext(Integer value) {log. d(TAG, "received event "+ value); } @override public void onError(Throwable e) {log.d (TAG, "response to Error "); } @override public void onComplete() {log.d (TAG, "response to Complete event "); }});Copy the code
  • The test results


Schematic diagram

The Sample ()

  • Function Sends only the latest (last) event in a period of time

Similar to the throttleLast () operator

  • The specific use

Just change the throttleLast () operator above to Sample (), which is not described here

ThrottleWithTimeout ()/debounce ()

  • If the interval of sending two data events is less than the specified time, the system discards the previous data. The system sends the latest data only when no new data is transmitted within the specified time

  • The specific use

Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) Throws Exception {// Interval event sending time e.onnext (1); Thread.sleep(500); e.onNext(2); Thread.sleep(1500); thread.sleep (1500); thread.sleep (1500); // Since the interval between 2 and 3 is longer than the specified 1s, the previously reserved 2 event is emitted e.onnext (3); Thread.sleep(1500); E.onnext (4) is emitted because the interval between 3 and 4 is longer than the specified 1s; Thread.sleep(500); // Because the interval between 4 and 5 is less than 1s, the first data (4) will be discarded, and the last data (5) will be retained. Thread.sleep(500); // Because the interval between 5 and 6 is less than 1s, the previous data (5) will be discarded, and 6 will be retained. Thread.sleep(1500); // Since the interval between 6 and the Complete practice is longer than the specified 1s, the previously reserved 6 event will issue e.oncomplete (); } }).throttleWithTimeout(1, Subscribe(new Observer<Integer>() {@override public void onSubscribe(Disposable d) {} @override public void onNext(Integer value) {log. d(TAG, "received event "+ value); } @override public void onError(Throwable e) {log.d (TAG, "response to Error "); } @override public void onComplete() {log.d (TAG, "response to Complete event "); }});Copy the code
  • The test results


Schematic diagram

3.4 Filtering events based on the specified event location

  • Requirement scenarios Filter events at a specified location by setting the location

  • Corresponding operator type


Schematic diagram

  • Use the corresponding operator

FirstElement ()/lastElement ()

  • Action only picks the first/last element

  • The specific use

Observable. Just (1, 2, 3, 4) 5) .firstElement() .subscribe(new Consumer<Integer>() { @Override public void accept( Integer integer) throws Exception {log. d(TAG," fetch first event: "+ integer); }}); Observable. Just (1, 2, 3, 4) 5) .lastElement() .subscribe(new Consumer<Integer>() { @Override public void accept( Integer integer) throws Exception { Log.d(TAG," the last event retrieved is: "+ integer); }});Copy the code
  • The test results


Schematic diagram


ElementAt ()

  • Function to receive an element (determined by index value)

Note: Allowed out of bounds, i.e. get the location index > send event sequence length

  • The specific use
// use 1: Observable. Just (1, 2, 3, 4,); 5) .elementAt(2) .subscribe(new Consumer<Integer>() { @Override public void accept( Integer integer) throws Exception { Log.d(TAG," fetch event elements: "+ integer); }}); // use 2: When the length of the event sequence is sent, Set the default Observable. Just (1, 2, 3, 4, 5).elementat (6,10).subscribe(new Consumer<Integer>() {@override public void accept(Integer Integer) throws Exception {log. d(TAG," fetch event elements: "+ integer); }});Copy the code
  • The test results


Schematic diagram

ElementAtOrError ()

  • Based on elementAt (), an exception is thrown when an out-of-bounds condition occurs (i.e. the location index obtained > the length of the sent event sequence)

  • The specific use

Observable.just(1, 2, 3, 4, 5) .elementAtOrError(6) .subscribe(new Consumer<Integer>() { @Override public void accept( Integer integer) throws Exception {log. d(TAG," fetch event elements: "+ integer); }});Copy the code
  • The test results


Schematic diagram

This concludes the explanation of the filter operators commonly used in RxJava2.


4. Actual development requirements cases

  • In the actual development, the common actual requirements of filtering operators are: function anti-shake & Lenovo search request optimization
  • In the following sections, I’ll illustrate these two requirements with examples

4.1 Function Shake Prevention

  • Demand scenarios


Schematic diagram

  • The specific use of the specific article: Android RxJava practical application explained: the function of anti-shake

4.2 Lenovo Search optimization

  • The scene that


Schematic diagram

  • Specific use of the specific article: Android RxJava actual application explained: Lenovo search optimization

5. The Demo address

All of the Demo source code above is stored in the Github address of Carson_Ho: RxJava2_ filter operator


6. Summary

  • Now, I’ll sum it up with a pictureRxJava2The common conditional/Boolean operator in


Schematic diagram

  • I’ll continue to dig into the other RxJava2 operators, but if you’re interested, stay with Carson_Ho’s Android development notes

Thumb up, please! Because your encouragement is the biggest power that I write!

Related articles reading

  • Android Rxjava: create operator Android Rxjava: create operator Android Rxjava: create operator Android Rxjava: create operator Android Rxjava: create operator Android Rxjava: create operator Android Rxjava: create operator Android Rxjava: create operator Android Rxjava: Android RxJava: A comprehensive tutorial on the functional operators
  • Android RxJava application description: (Unconditional) Network request polling Android RxJava application description: (conditional) Network request polling Android RxJava application description: Network request nested callback Android RxJava: merge data source Android RxJava: merge data from disk/memory cache: merge data from disk/memory cache Android RxJava: Network request error reconnection (Retrofit)

Welcome to attentionCarson_HoJane books!

Share the dry things about Android development from time to time, the pursuit of short, flat, fast, but there is no lack of depth.