RxJava - 似乎永远阻止的调试链

时间:2015-04-04 02:19:19

标签: android rx-java

我正在运行以下代码:

List<GroupedObservable<BcxToDoList, BcxToDo>> mToDoList;

mToDoList = bcxClient
  .fetchToDos()
  .flatMap(new Func1<List<BcxToDo>, Observable<BcxToDo>>() {
    @Override
    public Observable<BcxToDo> call(List<BcxToDo> bcxToDos) {
      return Observable.from(bcxToDos);
    }
  })
  .groupBy(new Func1<BcxToDo, BcxToDoList>() {
    @Override
    public BcxToDoList call(BcxToDo bcxToDo) {
      return bcxToDo.toDoList;
    }
  })
  .toList()
  .toBlocking()
  .single();

当我在Android Studio中使用此代码时,代码会无限期地阻塞。如果我使用subscribe()来捕获它,则没有例外。

调试正在进行的操作的最佳方法是什么?

更新

根据@ dwursteisen的建议,我使用.doOnNext()查看.groupBy()发出的内容。它创建了我期望的输出,它从未发送过onCompleted通知。

根据these tickets,在RxJava中,这是设计的。必须处理每个GroupedObservable才能使toList运算符起作用。

所以这是我修改后的代码:

List<BcxToDoList> mToDoList;

mToDoList = bcxClient
  .fetchToDos()
  .flatMap(new Func1<List<BcxToDo>, Observable<BcxToDo>>() {
    @Override
    public Observable<BcxToDo> call(List<BcxToDo> bcxToDos) {
      return Observable.from(bcxToDos);
    }
  })
  .groupBy(new Func1<BcxToDo, BcxToDoList>() {
    @Override
    public BcxToDoList call(BcxToDo bcxToDo) {
      return bcxToDo.toDoList;
    }
  })
  .flatMap( new Func1<GroupedObservable<BcxToDoList, BcxToDo>, Observable<BcxToDoList>>() {
    @Override
    public Observable<BcxToDoList> call(final GroupedObservable<BcxToDoList, BcxToDo> bcxToDoListBcxToDoGroupedObservable) {
      return bcxToDoListBcxToDoGroupedObservable
        .toList()
        .flatMap( new Func1<List<BcxToDo>, Observable<BcxToDoList>>() {
          @Override
          public Observable<BcxToDoList> call(List<BcxToDo> bcxToDos) {
            bcxToDoListBcxToDoGroupedObservable.getKey().toDos.addAll( bcxToDos );

            return Observable.just( bcxToDoListBcxToDoGroupedObservable.getKey() );
          }
        });
    }
  })

  .toList()

  .toBlocking()
  .single();

不如第一个代码片段那么优雅,但至少它不再阻止!如果我能做些什么来使新的代码片段更具可读性,我会很感激任何建议。

2 个答案:

答案 0 :(得分:1)

使用RxJava调试可能会很棘手。

您可以添加.doOnNext()调用,该调用将允许您显示RxJava通知并查看其中的通知。

根据你的代码,我认为当你使用toList运算符时你的代码块会在Observable完成时才会发出。

我认为你的流没有完成,因此toList永远不会发出,然后你的代码块永远都会被阻止。

答案 1 :(得分:1)

SO answer提供了调试RxJava的正确方法:

  

到现在为止,我无法重现这个问题,但我发现了rxdebug-java a   非常好的调试工具。

     

它的使用很简单:在应用程序中添加库作为依赖项   开始注册一个监听器:

RxJavaPlugins.getInstance().registerObservableExecutionHook(new DebugHook(new DebugNotificationListener() {
  public Object onNext(DebugNotification n) {
      Log.v(TAG,"onNext on "+n);
      return super.onNext(n);
  }


    public Object start(DebugNotification n) {
        Log.v(TAG,"start on "+n);
        return super.start(n);
    }


    public void complete(Object context) {
        super.complete(context);
        Log.v(TAG,"onNext on "+context);
    }

  public void error(Object context, Throwable e) {
      super.error(context, e);
      Log.e(TAG,"error on "+context);
  }
}));