Kenny
Kenny

Reputation: 815

ReactiveLocationProvider with RetroFit2 in Android throwing NetworkOnMainThread

The code below consistently throws a NetworkOnMainThread on Android, call attempt is to get a location and use it to fetch a list via a RetroFit 2 API, which works fine in other circumstances, as does the ReactiveLocation call.

new ReactiveLocationProvider(this).getLastKnownLocation()
  .singleOrDefault(null)
  .flatMap(new Func1<Location, Observable<List<OfferLocation>>>() {
    @Override
    public Observable<List<OfferLocation>> call(Location location) {
      return ARetrofitAPI.getOfferLocations(offer.getId(), latLng);
    }
  })
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe();

getLastKnownLocation() works fine and then the RetroFit wrapper call, that works EVERYWHERE else, throws NetworkOnMainThreadException, I've tried both 0.9 and 0.10, when either are by themselves in separate subscriptions all is fine.

The expected result would be for the result of the flatMap() to run on the io() Scheduler NOT on the mainThread().

android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:86)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
    at java.net.InetAddress.getAllByName(InetAddress.java:752)
    at okhttp3.Dns$1.lookup(Dns.java:39)
    at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:172)
    at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:138)
    at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:80)
    at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:178)
    at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:129)
    at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:98)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:109)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:124)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at com.greenlight.zubie.network.ZubieRetrofit$ZubieCallInterceptor.intercept(ZubieRetrofit.java:1063)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
    at okhttp3.RealCall.execute(RealCall.java:60)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
    at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request(RxJavaCallAdapterFactory.java:171)
    at rx.Subscriber.setProducer(Subscriber.java:211)
    at rx.internal.operators.OperatorMap$MapSubscriber.setProducer(OperatorMap.java:99)
    at rx.internal.operators.OperatorMap$MapSubscriber.setProducer(OperatorMap.java:99)
    at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:152)
    at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:138)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
    at rx.Observable.unsafeSubscribe(Observable.java:8666)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:250)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:147)
    at rx.internal.operators.OperatorMap$MapSubscriber.onNext(OperatorMap.java:74)
    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:227)
    at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Upvotes: 2

Views: 333

Answers (2)

Endrju
Endrju

Reputation: 46

In my case I have added .observeOn(Schedulers.io()) after getLastKnownLocation() and it works

Upvotes: 1

nasch
nasch

Reputation: 5498

I'm not sure but is this the problem?

By default, all network calls are synchronous:

RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.create();

If you wish to default network calls to be asynchronous, you need to use createWithScheduler().

RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());

Upvotes: 1

Related Questions