2017-04-19 76 views
0

我在Android中使用RxJava2的BehaviourSubject。在下面的链中,即使我subscribeOn(schedulers.background()),我也会收到一个NetworkOnMainThreadException。Android RxJava 2,subscribeOn与BehaviorSubject停留在MainThread

如果在searchRequestSubject后面使用ObserveOn(schedulers.background()),我会正确地进入后台线程。

我希望使用subscribeOn将获得所有链提供的线程?为什么它不以这种方式工作?

private BehaviorSubject<SearchRequest> searchRequestSubject = BehaviorSubject.create();

searchRequestSubject 
      .doOnEach(responseNotification -> Logger.d("Current Thread1: "+Thread.currentThread())) 
//.observeOn(schedulers.background()) // this is the current solution but 
      .flatMap(searchRequest -> adSearchService.getAds(searchRequest)) 
      .doOnEach(responseNotification -> Logger.d("Current Thread2: "+Thread.currentThread())) 
      .doOnNext(apiResponse -> updateResponseSubject(apiResponse)) 
      .doOnEach(responseNotification -> Logger.d("Current Thread3: "+Thread.currentThread())) 
      .subscribeOn(schedulers.background()) // this one should make the whole chain to subscribe on background. but it don't. why? 
      .subscribe() 

// Logs // 
Current Thread1: Thread[main,5,main] 
Current Thread2: Thread[main,5,main] 
Current Thread3: Thread[main,5,main] 

网络呼叫

public Observable<ApiResponse> getAds(@NonNull SearchRequest adRequest){ 
    if (adRequest == null){ 
     throw new IllegalStateException("Search Request should never be null"); 
    } 

    return apiService.getAdsObservable(token, adRequest.pageNumber(), adRequest.resultsNumberByPage(), adRequest.presentation(), 
      adRequest.toLatLongQuery(), adRequest.isClosed(), adRequest.toAdTypeQuery(), adRequest.category(), 
      adRequest.keywords(),adRequest.radius(), adRequest.from(), adRequest.to(), adRequest.isReserved(), adRequest.adId()) 
     .map(response -> handleResponseCode(response, adRequest.location())) 
     .onErrorReturn(error -> errorHandling.handleError(error)); 
} 

private ApiResponse handleResponseCode(Response<AdResponse> response, Location location) { 
    if (response.isSuccessful()){ 
     return AdSearchResponse.Response.create(response.body(), location); 
    } else if (response.code() == 404){ 
     return AdSearchResponse.NotFoundError.create(); 
    } else { 
     return errorHandling.handleError(response, null); 
    } 
} 

ApiService被改造2

@AutoValue 
public abstract class AppSchedulers { 
    public abstract Scheduler UI(); // AndroidSchedulers.mainThread() 
    public abstract Scheduler background(); // Schedulers.io() 
    // [...] creator and builder 
} 
+0

你有没有用'订阅试过()'但与其他兄弟节点,它需要的参数? – azizbekian

+0

是的,我已经删除了订阅中的数据清晰度 –

+0

正如在我的(删除)答案中所说的,您的代码适用于我。所以在我的网络请求中应该出现错误,我想 – GVillani82

回答

1

其实那是因为你使用的是热可观察到的(BehaviorSubject)好了,除非你是使用observeOn你会留在onNext的线程上。 subscribeOn将大部分时间用于冷观察。所以你的情况:

searchRequestSubject 
    .observeOn(schedulers.background()) 
    .doOnEach(responseNotification -> Logger.d("Current Thread1: "+Thread.currentThread())) 
    .flatMap(searchRequest -> adSearchService.getAds(searchRequest)) 
    .doOnEach(responseNotification -> Logger.d("Current Thread2: "+Thread.currentThread())) 
    .doOnNext(apiResponse -> updateResponseSubject(apiResponse)) 
    .doOnEach(responseNotification -> Logger.d("Current Thread3: "+Thread.currentThread())) 
    .subscribe() 

检查该链接,进入ObserveOn部分:http://tomstechnicalblog.blogspot.ca/2016/02/rxjava-understanding-observeon-and.html 你onNext就像是一个点击动作

0

后的愤怒,挫折和单元测试表明,它不因一个热/冷可观察问题。我清理了构建。重新启动的Android Studio。重新构建,并按预期工作,没有任何变化。

经常清理/重建的时候有任何疑问...