【问题标题】:Stack overflow when using Retrofit rxjava concatWith使用 Retrofit rxjava concatWith 时的堆栈溢出
【发布时间】:2015-06-09 06:12:03
【问题描述】:

我想使用 rxjava Observable 在 Retrofit 中处理分页。我听从了另一个question 的建议。

我有超过 100 个页面需要获取,但链在第 20 页左右失败,并停止对可观察对象的任何进一步订阅,并在 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)

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

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

【问题讨论】:

标签: java android retrofit rx-java rx-android


【解决方案1】:

所以,鉴于我回答了您提到的原始问题,我可能也应该尝试回答这个案例。 :)

这是我最初的寻呼答案的另一个有效(并且可能更简单)的替代方案,因为我已经在我的武器库中开发了更多的 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. */ });

【讨论】:

  • 终于解决了这个问题......已经想出了一个类似的方法并让它工作:)
  • 很棒的代码!我想现在Observable.range 也需要int start
  • 假设我有 1000 页是否可行/好?
  • 如果getResults(page) 订阅了不同的调度程序,这将不起作用。那时完全是不确定的行为。
猜你喜欢
  • 2015-08-26
  • 2019-05-18
  • 2015-03-28
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
  • 2011-05-16
相关资源
最近更新 更多