使用Retrofit 2和Rx在Scheduler.Worker线程上抛出致命异常

时间:2016-05-03 08:50:22

标签: android retrofit rx-java rx-android

这是我用来进行Http调用的代码。 我无法重现错误,但Bugsnag告诉我,有些用户收到此错误: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);
    }
}

以下是完整的跟踪:

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)

我还尝试订阅Sheduler.io()Scheduler.newThread(),但我收到同样的错误。

4 个答案:

答案 0 :(得分:4)

请注意,这不是永久性修复,但它对我有所帮助,可能对您有所帮助。发表评论太久了。

当我使用特定版本的改造时,您已经提到我注意到okhttp库存在一个错误(已经解决了),并且rx与改造集成。

我不知道修复的状态,但我有一个快速修复,它正在添加到rx流unsubscribeOn(Schedulers.io()),如下所示:

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);
                }
            });

答案 1 :(得分:1)

使用com.squareup.retrofit2:retrofit:2.0.2升级到okhttp3似乎解决了问题。

答案 2 :(得分:1)

我的经验和表明:

检查订阅者的onError(Throwable e)onCompleted()方法工具,是否有可能导致任何异常。例如,NullPointerException等。

Rxjava无法捕获从这两种方法抛出的异常。您将获得java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.您甚至无法从堆栈跟踪中找到异常源。

答案 3 :(得分:0)

Observable.create()如果你没有抓到,那么会发生错误。

Observable.create((Subscriber<? super Object subscriber) -> { // something wrong occur in here ,you can surround these codes by try catch });