Ich benutze ein BehaviourSubject mit RxJava2 in Android. In dieser folgenden Kette erhalte ich eine NetworkOnMainThreadException, selbst wenn ich subscribeOn (schedulers.background()) bin.Android RxJava 2, subscribeOn mit BehaviorSubject bleib auf MainThread
Wenn ich ObserveOn (schedulers.background()) direkt nach dem searchRequestSubject verwende, gehe ich richtig in einen Hintergrund-Thread.
Ich erwarte, dass die Verwendung von subscribeOn die gesamte Kette in den bereitgestellten Thread bekommen wird? Warum funktioniert es nicht so?
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]
Netzwerk Anruf
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 durch Retrofit bereitgestellt 2
@AutoValue
public abstract class AppSchedulers {
public abstract Scheduler UI(); // AndroidSchedulers.mainThread()
public abstract Scheduler background(); // Schedulers.io()
// [...] creator and builder
}
Haben Sie mit nicht 'subscribe versucht()' aber mit anderen Geschwistern, die nimmt Parameter? – azizbekian
Ja, ich habe die Daten im Abonnement für die Klarheit entfernt –
Wie in meiner (gelöschten) Antwort gesagt, funktioniert Ihr Code für mich. Es sollte also etwas Falsches in Ihrer Netzwerkanfrage sein, denke ich – GVillani82