zunächst alles, was Sie brauchen, um mit observeOn aller Gleichzeitigkeit loszuwerden und subscribeOn verwenden.
.observeOn(Schedulers.io())
Bitte beachten Sie bei AndroidScheduler mit observeOn wenn Sie möchten, Daten von einem anderen Thread synchronisieren zurück zur Event-Schleife. Normalerweise würden Sie observeOn verwenden, bevor Sie eine Observable abonnieren, um zurück zur ui-Schleife zu synchronisieren und ui-Informationen zu ändern.
.observeOn(AndroidSchedulers.mainThread())
Zweitens ist es nicht zu empfehlen, Objekte in der Pipeline zu mutieren. Sie sollten ein neues Objekt sehr oft zurückgeben.
.doOnNext(element -> item.image = element.attr("src"))
Ich habe versucht, Ihre Lösung unter Berücksichtigung der ersten beiden Punkte zu refaktorieren. Ich benutze RxJava2-RC5
Der flatMap-Operator hat viele Überblendungen. Eine davon bietet eine Funktion, um den eingehenden Wert und den erstellten Wert zusammenzufassen.
Observable<Rss> rssItemObservable = newsService.getDumpData()
.flatMap(rss -> getRssItemInformation(rss).subscribeOn(Schedulers.io()),
(r, rItemList) -> {
Rss rInterim = new Rss();
rInterim.items = rItemList;
return rInterim;
});
Hilfe-Methode zum Abrufen von Informationen für jedes Element in Rss. Bitte denken Sie daran, die Überladung mit maxConcurrency zu verwenden, da sie standardmäßig jeden Stream auf einmal abonniert. Daher würde flatMap viele http-Anfragen erstellen.
private Observable<List<RssItem>> getRssItemInformation(Rss rss) {
return Observable.fromIterable(rss.items)
.flatMap(rssItem -> getImageUrl(rssItem).subscribeOn(Schedulers.io()), (rItem, img) -> {
RssItem item = new RssItem();
printCurrentThread("merge1");
item.image = img;
item.link = rItem.link;
return item;
}).toList().toObservable();
}
Hilfe-Methode zum Abrufen der Bild-URL. Zurückkehrendes Observable ist nicht autorisiert über Gleichzeitigkeit. Wenn ein Fehler auftritt, wird eine leere Zeichenfolge als Standardwert zurückgegeben.
private Observable<String> getImageUrl(String link) {
return Observable.fromCallable(() -> Jsoup.connect(link).get())
.map(document -> document.select("div[itemprop=image] > img").first())
.map(element -> element.attr("src"))
.onErrorResumeNext(throwable -> {
return Observable.just("");
});
}
Sie können das vollständige Beispiel auf Github betrachten.gist: https://gist.github.com/anonymous/a8e36205fc2430517c66c802f6eef38e
Was versuchen Sie zu erreichen, indem Sie 'flatMap' Parameter auf' defaultIfEmpty' Parameter übergeben? Sie möchten eine Ausnahme abfangen? –
@ R.Zagórski es ist nur im Falle eines Fehlers seine Quelle ausstrahlen Observable – Mamadou
Erwarten Sie Fehler von 'newsAppService.getDumpData()' oder von Ihrer Umwandlung, um Bild zu erhalten? –