使用Retrofit rxjava concatWith时堆栈溢出

Bhu*_*van 15 java android rx-java retrofit rx-android

我想使用rxjava Observable处理Retrofit中的分页.我听从了另一个问题的建议.

我有超过100个页面需要被提取,但链在第20页的页面失败并停止对logserv的进一步订阅以及logcat中的以下日志

04-04 04:12:11.766    2951-3012/com.example.app I/dalvikvm? threadid=28: stack overflow on call to Ljava/util/concurrent/atomic/AtomicLongFieldUpdater$CASUpdater;.compareAndSet:ZLJJ
04-04 04:12:11.766    2951-3012/com.example.app I/dalvikvm? method requires 56+20+32=108 bytes, fp is 0x94b52350 (80 left)
04-04 04:12:11.766    2951-3012/com.example.app I/dalvikvm? expanding stack end (0x94b52300 to 0x94b52000)
04-04 04:12:11.766    2951-3012/com.example.app I/dalvikvm? Shrank stack (to 0x94b52300, curFrame is 0x94b548dc)
Run Code Online (Sandbox Code Playgroud)

有人知道为什么会这样吗?

更新:我知道这是由于递归而发生的,但是有一种更优雅的方式来处理改装和rxjava的分页吗?

lop*_*par 27

所以,鉴于我回答了您引用的原始问题,我应该尝试回答这个案例.:)

这是我原来的分页答案的另一个有效(并且可能更简单)的替代方案,现在我已经在我的军火库中开发了一些Rx技巧.:)(完成java8 lambda样式的伪代码):

Observable.range(Integer.MAX_VALUE)
    // Get each page in order.
    .concatMap(page -> getResults(page))
    // Take every result up to and including the one where the next page index is null.
    .takeUntil(result -> result.next == null)
    // Add each output to a list builder. I'm using Guava's ImmutableList, but you could
    // just as easily use a regular ArrayList and avoid having to map afterwards. I just
    // personally prefer outputting an immutable data structure, and using the builder
    // is natural for this.
    //
    // Also, if you wanted to have the observable stream the full output at each page,
    // you could use collect instead of reduce. Note it has a slightly different syntax. 
    .reduce(
        ImmutableList.<ResponseObject>builder(),
        (builder, response) -> builder.addAll(response.results))
    // Convert list builder to one List<ResponseObject> of all the things.
    .map(builder -> builder.build())
    .subscribe(results -> { /* Do something with results. */ });
Run Code Online (Sandbox Code Playgroud)

  • 真棒代码!我想现在`Observable.range`也需要`int start`! (3认同)