preface
-
Rxjava
Because of itsChain call based on event flow, simple logic & easy to useThe characteristics of the deepAndroid
Developer welcome.
Making screenshots
If you are not familiar with RxJava, check out Android: a clear and easy-to-understand introduction to RxJava
-
RxJava
That’s why it’s so popularProvides rich & powerful operators that can fulfill almost all functional requirements - Today, I will give you a detailed introduction
RxJava
The most commonly used of the operatorsFilter operatorI hope you like it.
- This series of articles is based on
Rxjava 2.0
- 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:
- Filter events based on specified conditions
- Filter events based on the specified number of events
- Filter events based on the specified time
- 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 picture
RxJava2
The 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.