即使指定了subscribeOn,代码也在主线程上运行

时间:2017-02-16 16:32:44

标签: java android rx-java

我正在将AsyncTaskLoader迁移到RxJava,试图了解有关RxJava并发方法的所有细节。简单的东西运行正常,但我正在努力使用以下代码:

这是执行的顶级方法:

mCompositeDisposable.add(mDataRepository
            .getStuff()
            .subscribeOn(mSchedulerProvider.io())
            .subscribeWith(...)

mDataRepository.getStuff()如下所示:

public Observable<StuffResult> getStuff() {
    return mDataManager
            .listStuff()
            .flatMap(stuff -> Observable.just(new StuffResult(stuff)))
            .onErrorReturn(throwable -> new StuffResult(null));

最后一层:

 public Observable<Stuff> listStuff() {
        Log.d(TAG, ".listStuff() - "+Thread.currentThread().getName());
        String sql = <...>;
        return mBriteDatabase.createQuery(Stuff.TABLE_NAME, sql).mapToList(mStuffMapper);
 }

因此,使用上面的代码,log将打印出.listStuff() - main,这不是我正在寻找的。而且我不确定为什么。我的印象是,通过设置subscribeOn,从链中拉出的每个事件都将在subscribeOn方法中指定的线程上处理。

我认为正在发生的事情是,在到达mBriteDatabase之前,源 - 又 - 最后层代码不是来自RxJava世界,因此在调用createQuery之前不是事件。所以我可能需要某种包装?我已经尝试应用.fromCallable,但是这是非Rx代码的包装器,我的数据库层返回一个可观察的...

1 个答案:

答案 0 :(得分:3)

您的Log.d来电正确

  • listStuff被召唤时立即
  • 在getStuff被调用后立即
  • 这是您向我们展示的顶级代码片段中发生的第一件事。

如果您需要在订阅发生时执行此操作,则需要明确:

public Observable<Stuff> listStuff() {
    String sql = <...>;
    return mBriteDatabase.createQuery(Stuff.TABLE_NAME, sql)
      .mapToList(mStuffMapper)
      .doOnsubscribe(() -> Log.d(TAG, ".listStuff() - "+Thread.currentThread().getName()));
}