RxTips – Rechercher un utilisateur sur un webservice
Prenons un cas usuel dans nos applications android : la recherche d’un utilisateur dans notre webservice, en fonction d’un texte saisi part l’utilisateur.
Pour cela, nous ajoutons un TextWatcher sur notre EditText, et donc dès que texte change, nous appelons notre webservice afin qu’il nous renvoie les utilisateurs dont le nom contient le texte rentré.
editText.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, int count) { } @Override public void afterTextChanged(Editable s) { String name = s.toString(); if(name.length() > 3) { //cet appel est effectué à chaque fois que l'utilisateur modifie le texte webservice.searchUser(name) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(users -> { recyclerAdapter.displayUsers(users); }); } } });
Le rendu ne sera pas très fluide, pour chaque lettre retirée / ajoutée, un appel est directement envoyé au webservice…
Voyons ensemble comment RxIfier cela ! (ouai j’ai inventé ce verbe :P)
RxBindings
Ajoutons la librairie RxBindings à notre build.gradle
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
Puis utilisons RxTextView.textChanges sur notre editText au lieu de addTextChangedListener
RxTextView.textChanges(editText) .map(CharSequence::toString) .filter(text -> text.length() > 3) .flatMap(text -> webservice.search(text)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(users -> { recyclerAdapter.displayUsers(users); });
Limiter les appels réseau
Nous allons utiliser un opérateur de gestion de flux Rx afin de limiter les appels à notre webservice.
Ici, l’utilisation de throttleWithTimeout va faire en sorte de ne prendre en compte qu’un seul changement de texte (supérieur à 3 caractères) toutes les 5 secondes.
RxTextView.textChanges(editText) .map(CharSequence::toString) .filter(text -> text.length() > 3) //ne prend qu'une valeur toutes les 5 secondes .throttleWithTimeout(5, TimeUnit.SECONDS) .flatMap(webservice::search) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(recyclerAdapter::displayUsers);
L’interface sera plus fluide, et cela limitera l’utilisation de la bande passante (pensez à vos utilisateurs qui sont encore en 3G :P)
Un peu perdu en RxJava ? n’hésitez pas à aller faire un tour sur notre un article d’introduction sur RxJava , ainsi que celui détaillant l’utilisation des lambdas.
Petit rappel on vient de lancer une nouvelle rubrique sur le site, où vous pouvez découvrir des livres et des Goodies Android, allez-y faire un tour 😀