2017-04-19 20 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。重新構建,並按預期工作,沒有任何變化。

經常清理/重建的時候有任何疑問...

相關問題