Используйте RxJava и Retrofit для перебора списка и увеличения результатов на основе подзапросов
Я использую модификацию, и мне кажется, что rxjava (с retrolambda) будет хорошо подходит для следующего потока:
Однако я не уверен, что делать после шага 2а. Здесь мой код пока
apiService.getWidgets(token)
.flatMapIterable(widgets -> widgets)
.flatMap(widget -> apiService.getArticles(token, widget.type))
...
.toList()
.subscribe(
modifiedWidgets -> saveWidgets(modifiedWidgets),
throwable -> processWidgetError(throwable)
);
Я играл с некоторыми операторами, но, когда вы цепляетесь, я всегда сужу слишком далеко (например, получить дескриптор одной статьи), а затем больше не иметь доступа к оригинальный виджет для внесения изменений.
@GET("/widgets")
Observable<List<Widget>> getWidgets(@Header("Authorization") String token);
@GET("/articles")
Observable<List<Article>> getArticles(@Header("Authorization") String token, @Query("type") String type);
Ответы
Ответ 1
Вы можете вставить doOnNext в определенные моменты потока, чтобы добавить побочные эффекты:
apiService.getWidgets(token)
.flatMapIterable(v -> v)
.flatMap(w ->
apiService.getArticles(token, w.type)
.flatMapIterable(a -> a)
.doOnNext(a -> db.insert(a))
.doOnNext(a -> {
w.articleName = a.name;
w.articleUrl = a.url;
})
.takeLast(1)
.map(a -> w)
)
.toList()
.subscribe(
modifiedWidgets -> saveWidgets(modifiedWidgets),
throwable -> processWidgetError(throwable)
);
Ниже приведен пример выполнения.
Ответ 2
добавив это здесь, так как я не смог найти пример итерации списка, который возвращается в объекте как переменная.
getUserAccount(token)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(userResponse -> Observable.just(userResponse.list)) //get list from response
.flatMapIterable(baseDatas -> baseDatas) //make the list iterable
.flatMap(baseData -> //on each project, get the details
getProjectDetails(baseData.name,token)
.subscribeOn(Schedulers.io()) //get network call off the main thread
.observeOn(AndroidSchedulers.mainThread()))
.subscribe(
(dataResponse) -> {
Timber.d( "Got Data Details:" + dataResponse);
},
(error) -> {
Timber.e( "Got Error:" + error.getMessage());
},
() -> {
Timber.d("Completed Data Details");
}
);
Ответ 3
Ответ akarnokd весьма полезен, но может вызвать NetworkOnMainThreadException
.
Чтобы решить эту проблему, я добавил
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
для каждого запроса
apiService.getWidgets(token)
.observeOn(AndroidSchedulers.mainThread()) //added this
.subscribeOn(Schedulers.io()) //added this
.flatMapIterable(v -> v)
.flatMap(w ->
apiService.getArticles(token, w.type)
.observeOn(AndroidSchedulers.mainThread()) //added this
.subscribeOn(Schedulers.io()) //added this
.flatMapIterable(a -> a)
.doOnNext(a -> db.insert(a))
.doOnNext(a -> {
w.articleName = a.name;
w.articleUrl = a.url;
})
.takeLast(1)
.map(a -> w)
)
.toList()
.subscribe(
modifiedWidgets -> saveWidgets(modifiedWidgets),
throwable -> processWidgetError(throwable)
);