使用Retrofit和RxJava的concatWith方法时出现堆栈溢出错误

16

我希望使用rxjava Observable在Retrofit中处理分页。我遵循另一个问题中的建议。

我需要获取超过100个页面,但是在第20页左右链条失败并且停止了对可观察对象的任何进一步订阅,日志如下所示:

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)

有人知道为什么会发生这种情况吗?

更新:我知道这是由于递归引起的,但是有没有更优雅的处理分页与retrofit和rxjava结合的方法?


1个回答

30

因此,考虑到我已回答了您所提到的原始问题,我可能应该尝试回答这个案例。 :)

这是另一种有效(且可能更简单)的选项,用了我在武器库中开发出来的一些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. */ });

终于有时间来搞了…之前想到过类似的方法并且已经实现了 :) - Bhuvan
3
太棒了!我猜现在Observable.range还需要一个int start参数! - Kayan Almeida
假设我有1000页,这可行/好吗? - Ajinkya
如果getResults(page)在不同的调度程序上订阅,那么这将无法工作。此时完全是非确定性行为。 - AutonomousApps

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接