Meine App hat eine SearchView. Wenn der Benutzer das SearchView eingibt, übergibt die OnQueryTextChange die Abfrage an den Referenten und dann ruft es die API auf. Ich verwende Retrofit und RxJava für die Anrufe. Die Aufrufe geben eine JSON-Datei mit den Wörtern zurück, die enthalten, was der Benutzer bisher eingegeben hat. Das Problem ist, dass, wenn der Benutzer schnell Buchstaben eingibt und das Netzwerk langsam ist, das SearchView die Ergebnisse nicht auf der Grundlage aller eingegebenen Buchstaben zeigt, sondern vielleicht bis zum vorletzten, weil der letzte Aufruf schneller war, um die Ergebnisse zu erhalten verglichen mit dem vorletzten.synchrone Anrufe mit rxjava Android
Beispiel: der Benutzer Start Typisierung:
"COU" -> machen einen Aufruf an die API (erst nach 3 Buchstaben rufen) -> starten returnin
Werte"n" -> make a rufen -> Startwert Rückkehr
"t" -> Anruf -> Startwert
"r" Rückkehr -> Anruf (die Verbindung langsam ist)
„y“ -> Anruf -> Startwerte Rückkehr
-> „r“ endlich die Ergebnisse erhalten und die Erträge sie
public Observable<List<MyModel>> getValues(String query) {
return Observable.defer(() -> mNetworkService.getAPI()
.getValues(query)
.retry(2)
.onErrorReturn(e -> new ArrayList<>()));
}
Der Anruf ist sehr einfach und wenn ich erhalte eine Fehlermeldung I will nichts anzeigen.
Gibt es eine Möglichkeit, das zu lösen? Oder ist dies bei reaktiver Programmierung nicht der Fall?
EDIT: nur klarer zu machen, der Fluss ist die folgende:
Aktivität, die eine benutzerdefinierte Suche verwendet (https://github.com/Mauker1/MaterialSearchView)
der Brauch Suche hat einen Hörer, wenn der Benutzer beginnt zu tippen. Sobald der Benutzer beginnt, die Aktivität einzugeben, ruft der Presenter auf.
der Moderator wird eine beobachtbare zurück vom Interaktorsystem abonnieren:
Moderator:
addSubscription(mInteractor.getValues(query)
.observeOn(mMainScheduler)
.subscribeOn(mIoScheduler)
.subscribe(data -> {
getMvpView().showValues(data);
}, e -> {
Log.e(TAG, e.getMessage());
}));
Interaktorsystem:
public Observable<List<MyModel>> getValues(String query) {
return Observable.defer(() -> mNetworkService.getAPI()
.getValues(query)
.debounce(2, TimeUnit.SECONDS)
.retry(2)
.onErrorReturn(e -> new ArrayList<>()));
So, jetzt entweder ich die benutzerdefinierte Suchansicht ändern in einer 'normalen' Suchansicht und dann RxBinding verwenden oder vielleicht sollte ich einen Handler verwenden o r so etwas (aber immer noch zu kämpfen, wie es in meiner Architektur passen)
Interessante RxBinding. Ich werde es versuchen und ich werde es dich wissen lassen. Ich habe versucht, bereits zu entprellen, aber aus irgendwelchen Gründen hat es nicht funktioniert. Vielleicht habe ich etwas falsch gemacht. Heute werde ich es nochmal versuchen. Danke! – user1341300
Ich glaube nicht, dass ich RxBinding verwenden kann. Ich habe ein paar Dinge ausprobiert, aber es sieht cool aus, aber im Moment benutze ich eine benutzerdefinierte Suchansicht (es ist ein erweitertes Koordinatorlayout mit einem Bearbeitungstext, der von https://github.com/Mauker1/MaterialSearchView stammt). – user1341300
Dann verwenden 'RxTextView.textChanges()' mit 'switchMap()' – EpicPandaForce