Fatal Exception thrown on Scheduler.Worker thread with Retrofit 2 and Rx
Solution 1
It looks like upgrading to com.squareup.retrofit2:retrofit:2.0.2
using okhttp3
solved 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.
Related videos on Youtube
Jérôme Boé
Updated on July 01, 2022Comments
-
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()
andScheduler.newThread()
, but I get the same error.