Ich habe eine Observable<<List<Foo>> getFoo()
, die von einem Retrofit Service erstellt wird und nach dem Aufruf der .getFoo()
Methode muss ich es mit mehreren Abonnenten teilen. Wenn die Methode .share()
aufgerufen wird, wird der Netzwerkaufruf jedoch erneut ausgeführt. Replay Operator funktioniert auch nicht. Ich weiß, dass eine mögliche Lösung .cache()
sein könnte, aber ich weiß nicht, warum dieses Verhalten verursacht wird.Single Observable mit mehreren Abonnenten
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
// Create an instance of our GitHub API interface.
// Create a call instance for looking up Retrofit contributors.
Observable<List<Contributor>> testObservable = retrofit
.create(GitHub.class)
.contributors("square", "retrofit")
.share();
Subscription subscription1 = testObservable
.subscribe(new Subscriber<List<Contributor>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onNext(List<Contributor> contributors) {
System.out.println(contributors);
}
});
Subscription subscription2 = testObservable
.subscribe(new Subscriber<List<Contributor>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onNext(List<Contributor> contributors) {
System.out.println(contributors + " -> 2");
}
});
subscription1.unsubscribe();
subscription2.unsubscribe();
Der obige Code kann das oben genannte Verhalten reproduzieren. Sie können es debuggen und sehen, dass die empfangenen Listen zu einer anderen MemoryAddress gehören.
Ich habe auch ConnecableObservables als eine mögliche Lösung betrachtet, aber dies erfordert, dass ich das Original Observable herumtragen und jedes Mal, wenn ich einen neuen Abonnenten hinzufügen möchte, .connect()
aufrufen.
Diese Art von Verhalten mit der .share()
funktionierte gut bis Retrofit 1.9. Es hat aufgehört, an Retrofit 2 - beta zu arbeiten. Ich habe es noch nicht mit der Retrofit 2 Release Version getestet, die vor einigen Stunden veröffentlicht wurde.
EDIT: 01/02/2017
Für zukünftige Leser, ich habe einen Artikel geschrieben here mehr über den Fall zu erklären!
Vielen Dank für Ihre Antwort. Die Sache ist, dass ich wirklich vermeiden möchte, jedes Mal Verbindung anzurufen. Sind Sie sicher, dass der Replay-Operator mit diesem Anwendungsfall gut funktioniert? – Pavlos
Eigentlich habe ich es getestet und es hat funktioniert. Vielen Dank für Ihre Zeit und Ihre Antwort. Nur um des Problems willen habe ich den Unterschied zwischen den heißen und kalten Observablen gelesen, konnte es aber nicht mit den Netzwerkaufrufen mit Retrofit reproduzieren. Wenn ich eine Observable.just() verwendet, funktioniert der Share-Operator ziemlich gut. – Pavlos