Fatal Exception thrown on Scheduler.Worker thread with Retrofit 2 and Rx

14,739

Solution 1

It looks like upgrading to com.squareup.retrofit2:retrofit:2.0.2 using okhttp3solved the problem.

Solution 2

Note this isn't a permanent fix, but it helped me and might help you. It's too long to put in a comment.

While I was using the specific version of retrofit you've mentioned I noticed there was a bug (already being addressed) with the okhttp library and the rx integration with retrofit.

I don't know the state of the fix, but I have a quick fix which was adding to the rx stream unsubscribeOn(Schedulers.io()), like so:

observable.subscribeOn(Schedulers.computation())
            .observeOn(AndroidSchedulers.mainThread())
            .unsubscribeOn(Schedulers.io())
            .subscribe(new Subscriber<T>() {
                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable e) {
                    callback.onError(e);
                }

                @Override
                public void onNext(T result) {
                    callback.onSuccess(result);
                }
            });

Solution 3

My experience & suggests:

Check your onError(Throwable e) and onCompleted() method implement of Subscriber, is any possible may cause any exception. For example, NullPointerException etc.

Rxjava can not catch the exception which throw from this two method. And you will get java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread. Which you even can't locate the exception source from the stack trace.

Share:
14,739

Related videos on Youtube

Jérôme Boé
Author by

Jérôme Boé

Updated on July 01, 2022

Comments

  • Jérôme Boé
    Jérôme Boé almost 2 years

    This is the code I use to make Http call. I can't reproduce the error, but Bugsnag tells me that some users are getting this error : java.lang.IllegalStateException StrictMode.java

    public class ApiManager {
        public interface Callback<T> {
            void onError(Throwable e);
    
            void onSuccess(T result);
        }
    
        private ApiService _apiService;
    
        public ApiManager() {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BuildConfig.BASE_URL)
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(ew OkHttpClient())
                    .build();
            _apiService = retrofit.create(ApiService.class);
        }
    
        private <T> void execute(Observable<T> observable, final Callback<T> callback) {
            observable.subscribeOn(Schedulers.computation())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<T>() {
                        @Override
                        public void onCompleted() {
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            callback.onError(e);
                        }
    
                        @Override
                        public void onNext(T result) {
                            callback.onSuccess(result);
                        }
                    });
        }
    
        public void createUser(Callback<Void> callback) {
            execute(_apiService.createUser(new User()), callback);
        }
    
        // Retrofit Service
        public interface ApiService {
            @POST("users")
            Observable<Void> createUser(@Body User user);
        }
    }
    

    Here is the full trace :

    java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:153)
            at android.app.ActivityThread.main(ActivityThread.java:5340)
            at java.lang.reflect.Method.invokeNative(Method.java:-2)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(NativeStart.java:-2)
    Caused by: rx.exceptions.UnsubscribeFailedException
            at rx.observers.SafeSubscriber.onCompleted(SafeSubscriber.java:98)
            at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:195)
            at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:162)
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:153)
            at android.app.ActivityThread.main(ActivityThread.java:5340)
            at java.lang.reflect.Method.invokeNative(Method.java:-2)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(NativeStart.java:-2)
    Caused by: android.os.NetworkOnMainThreadException
            at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128)
            at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:906)
            at com.squareup.okhttp.Connection.closeIfOwnedBy(Connection.java:148)
            at com.squareup.okhttp.OkHttpClient$1.closeIfOwnedBy(OkHttpClient.java:75)
            at com.squareup.okhttp.internal.http.HttpConnection.closeIfOwnedBy(HttpConnection.java:137)
            at com.squareup.okhttp.internal.http.HttpTransport.disconnect(HttpTransport.java:135)
            at com.squareup.okhttp.internal.http.HttpEngine.disconnect(HttpEngine.java:573)
            at com.squareup.okhttp.Call.cancel(Call.java:122)
            at retrofit.OkHttpCall.cancel(OkHttpCall.java:162)
            at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe$1.call(RxJavaCallAdapterFactory.java:102)
            at rx.subscriptions.BooleanSubscription.unsubscribe(BooleanSubscription.java:71)
            at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124)
            at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113)
            at rx.Subscriber.unsubscribe(Subscriber.java:98)
            at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124)
            at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113)
            at rx.Subscriber.unsubscribe(Subscriber.java:98)
            at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124)
            at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113)
            at rx.Subscriber.unsubscribe(Subscriber.java:98)
            at rx.observers.SafeSubscriber.onCompleted(SafeSubscriber.java:95)
            at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:195)
            at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:162)
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:153)
            at android.app.ActivityThread.main(ActivityThread.java:5340)
            at java.lang.reflect.Method.invokeNative(Method.java:-2)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(NativeStart.java:-2)
    

    I also tried to subscribe on Sheduler.io() and Scheduler.newThread(), but I get the same error.