2017-04-19 15 views
0

AndroidでRavJava2でBehaviourSubjectを使用しています。この次のチェーンでは、私がsubscribeOn(schedulers.background())を実行してもNetworkOnMainThreadExceptionを受け取ります。Android RxJava 2、subscribeOn BehaviorSubject with 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は実際に

@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)を使用しているからだとレトロフィット2によって提供され、あなたがある場合を除きれます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を再起動しました。もう一度ビルドし、変更なしに期待どおりに動作していました。

何の疑いも常にクリーン/リビルド...

関連する問題