NetworkOnMainThread 在 Android 中使用 AsyncSubject RxJava

NetworkOnMainThread using AsyncSubject RxJava in Android

即使我在返回的 Observable 中应用调度程序,我仍面临 AsyncSubject 上的 NetworkOnMainThreadException。 为什么我们需要在 Subject 上应用 Schedulers

我在 Subjects 的 javadoc 中错过了这个解释,如果我们不组合它,为什么 Subject 会进入主线程?有人可以指出解释这个的文档吗?

下面有一个代码示例来说明该场景。

这是用例:

/*** Makes a network call to retrieve a search result, it returns an Observable<SearchResult> */
private Observable<SearchResult> call(String searchQuery){
    return mSearchWebService.call(searchQuery);
}

/* Same code but with a  a NetworkOnMainThreadException */
private Observable<SearchResult> call(String searchQuery){
    final Subject<SearchResult, SearchResult> subject = AsyncSubject.create();
    mSearchWebService.call(“let me google something”)
            .subscribe(subject::onNext, subject::onError, subject::onCompleted);
    // When we apply the schedulers in the subject, it works fine, but why it doesn’t apply the schedulers of the observables?
    // This works: mSearchWebService.call(“let me google something”)
    // .compose(mBackgroundThreadTransformer.applySchedulers())
    // .subscribe(subject::onNext, subject::onError, subject::onCompleted);
    return subject;
}

这是演示者中的代码:

private void onSearchButtonClicked(){
    searchUseCase.call(“let me google something”).compose(mBackgroundThreadTransformer.applySchedulers())
        .subscribe(searchResult -> show(searchResult),
            e -> Timber.d(e, "Failed to search”)));
}

让我们分析一下行为。

从不 return NetworkOnMainThreadException 的第一种方法开始,您将调度程序应用到 Observable return 由 mSearchWebService.call(searchQuery) 编辑。很清楚了。

第二种情况呢?您创建 Subject 和 return 它并将调度程序应用于从函数 return 编辑的内容。 Subject 是 returned 并且它获取调度程序。 mSearchWebService.call(“let me google something”) 未由 mBackgroundThreadTransformer

安排

mSearchWebService.call(...)的角度来看,Subject是什么?就是Subscriber。所以 mSearchWebService.call(...) ends (without assigning any particularScheduler) passing the result toSubject(which runs onmBackgroundThreadTransformer) which passes the result to the endSubscriber`.

解决方法: 明确地将 Scheduler 应用于 mSearchWebService.call(...)