Rxjava uses the debounce operator to optimize the app search function __debounce

Source: Internet
Author: User
Tags throwable

Problem

Almost all apps now have search capabilities, and generally we listen to edittext controls and change the value to request a search interface. Such as:

Etkey.addtextchangedlistener (New Textwatcher () {
    @Override public
    void beforetextchanged (charsequence s, int Start, int count, int after) {
    }

    @Override public
    void ontextchanged (charsequence s, int start, int before, T count) {
    }

    @Override public
    void aftertextchanged (Editable s) {
        String key = Etkey.gettext (). toString (). Trim ();
        if (key.length () > 0) {Search
            (key),//Request search interface, after successful display the results to the interface.}}
);

There are two problems with this: it can lead to a lot of meaningless requests, consuming user traffic (because the value of the control immediately requests the network every time it changes, and only the last keyword entered is useful) may result in a final search that is not what the user wants. For example, when the user first enters the keyword ' AB ' This time there are two requests, one request is a keyword, and one request is the AB keyword. On the surface is ' A ' request to send out first, ' AB ' after the request sent out. If the ' AB ' request is sent back first and the ' a ' request is returned, the result of the ' a ' request will overwrite the result of the ' AB ' request. resulting in incorrect search results.

Solve the problem

This problem can be solved by using the powerful Rxjava debounce operator.

subscription = Rxtextview.textchanges (Etkey). Debounce (Timeunit.milliseconds, Androidschedulers.maint Hread ()). Subscribeon (Androidschedulers.mainthread ())//to Etkey[edittext] is required to operate in the main thread
                    User-entered keywords are filtered. Filter (new func1<charsequence, boolean> () {@Override Public Boolean called (charsequence charsequence) {log.d ("Rxjava", "Filter is main thread:
                        "+ (looper.getmainlooper () = = Looper.mylooper ()));
                    Return charsequence.tostring (). Trim (). Length () > 0;
                    }). Flatmap (New func1<charsequence, observable<list<string>>> () { @Override Public observable<list<string>> Call (Charsequence charsequence)
                        {LOG.D ("Rxjava", Getmaintext ("Flatmap")); Return Searchapi.search (ChArsequence.tostring ()); }). Subscribeon (Schedulers.io ()). Observeon (Androidschedulers.mainthread
                    ()). Subscribe (New action1<list<string>> () {@Override
                        public void call (List<string> strings) {tvcontent.settext ("search result:\n\n");
                    Tvcontent.append (Strings.tostring ()); The new action1<throwable> () {@Override public void call (T
                        Hrowable throwable) {throwable.printstacktrace ();
                    Tvcontent.append ("Error:" + throwable.getmessage ()); }
                });

The main logic of the above code: using the Debounce operator setting: Only 400 milliseconds after the user enters the keyword to launch the data [the straightforward point is that it will take 400 milliseconds to walk behind the logic]; Use the filter operator to filter the keywords entered by the user: Only the keyword entered is not empty, Will go behind the logic; use the FLATMAP operator: Use the final keyword to request the search interface

At this point, avoid edittext every time a change is requested.

However, there is a problem, which is caused by the confusion of search results, the above code is not resolved, such as stop typing 400 milliseconds, then will certainly start requesting the search interface, but the user will enter a new keyword, this time the last request has not returned, The new request asks for the search interface. This time it is possible to return the last request, the first request returned, resulting in the final display result is the first search results.

How to solve this problem: You can use the SWITCHMAP operator to solve.

See how the official website explains the SWITCHMAP operator:

Returns a new observable by applying a function that you supply to each item emitted by the source observable that Returns An observable, and then emitting the items emitted by most recently emitted 
.

The switchmap operator is similar to the FLATMAP operator, and the difference is that the SWITCHMAP operator will only launch the nearest observables of [emit].

That is, when the first search request is issued after 400 milliseconds, the user searches again for the request, sending a second request, however, the SWITCHMAP operator will only launch a second request observable. Therefore, in the above code based on the Flatmap change to Switchmap on it.

Functional practical, really more and more like Rxjava.

Reprint: http://blog.csdn.net/johnny901114/article/details/51555203

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.