Android:使用Rx android和Retrofit时出现NetworkOnMainThreadException错误。

8 浏览
0 Comments

Android:使用Rx android和Retrofit时出现NetworkOnMainThreadException错误。

当使用rx android和retrofit时,我遇到了网络线程异常。这是我的代码:\n

public Observable requestApiItem() {
    return getauthenticationtoken.getToken().flatMap(new Func1>() {
        public Observable call(String token) {
            return service.postdata(value1, value2, value3, token);
        }
    }).subscribeOn(Schedulers.io());
}
public void postdata() {
    requestApiItem()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber() {
                @Override
                public void onCompleted() {
                    System.out.print("Complete");
                }
                @Override
                public void onError(Throwable e) {
                    System.out.print("Fail");
                }
                @Override
                public void onNext(PostVariablesModel apiResult) {
                    System.out.print(apiResult.toString());
                }
            });
}

\n在完成http调用后,我们需要取消订阅吗?有什么想法吗?\n异常如下所示。我在代码中的postdata方法的onError方法中遇到了这个异常:\n

android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
                                                                      at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
                                                                      at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
                                                                      at java.net.InetAddress.getAllByName(InetAddress.java:215)
                                                                      at okhttp3.Dns$1.lookup(Dns.java:39)
                                                                      at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:170)
                                                                      at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:136)
                                                                      at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:81)
                                                                      at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:171)
                                                                      at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
                                                                      at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
                                                                      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:93)
                                                                      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:120)
                                                                      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
                                                                      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
                                                                      at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
                                                                      at okhttp3.RealCall.execute(RealCall.java:63)
                                                                      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.Subscriber.setProducer(Subscriber.java:205)
                                                                      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.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:739)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                      at android.os.Looper.loop(Looper.java:158)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:7231)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

0
0 Comments

问题出现的原因是在postdata()方法中,requestApiItem()方法没有在后台线程中执行,而是在主线程中执行,导致了NetworkOnMainThreadException异常。

解决方法是将requestApiItem()方法放在后台线程中执行。可以使用RxAndroid和Retrofit的线程调度功能来实现。具体的解决方法是在postdata()方法中,使用observeOn()方法指定观察者在主线程中执行,使用subscribeOn()方法指定被观察者在后台线程中执行。代码如下:

public void postdata() {
    requestApiItem()
            .observeOn(AndroidSchedulers.mainThread()) // 指定观察者在主线程中执行
            .subscribeOn(Schedulers.io()) // 指定被观察者在后台线程中执行
            .subscribe(new Subscriber<PostVariablesModel>() {
                public void onCompleted() {
                    System.out.print("Complete");
                }
                public void onError(Throwable e) {
                    System.out.print("Fail");
                }
                public void onNext(PostVariablesModel apiResult) {
                    System.out.print(apiResult.toString());
                }
            });
}

另外,也可以尝试使用上面编辑中给出的解决方法,将requestApiItem()方法中的flatMap()方法替换为简单地使用Observable.just()方法返回结果。具体代码如下:

public Observable<PostVariablesModel> requestApiItem() {
    return service.postdata(value1, value2, value3, token)
            .flatMap(new Func1<PostVariablesModel>() {
                public Observable<? extends PostVariablesModel> call(PostVariablesModel yourModel) {
                    return Observable.just(yourModel);
                }
            });
}

以上是解决Android中使用RxAndroid和Retrofit时出现NetworkOnMainThreadException异常的原因和解决方法。

0
0 Comments

Android : NetworkOnMainThreadException using Rx android and Retrofit

在使用RxAndroid和Retrofit时出现了NetworkOnMainThreadException异常。根据问题相关的讨论,从代码中可以看到以下几点:

1. 在getauthenticationtoken.getToken()方法中,使用了.subscribeOn(Schedulers.io())指定了线程为io线程。

2. 在Retrofit的Builder中,使用了RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io())指定了调度器为io线程。

然而,尽管已经进行了正确的修正,仍然出现了相同的错误。在问题讨论中提到,没有在log cat中看到任何错误,应用程序也没有因此而崩溃。

根据回答中提供的链接,可以看到在UI线程上允许网络请求并不是解决问题的方法。此外,还提供了一个示例代码,但是这并不是一个好的解决方法。

通过进一步探讨,发现问题出现在某个Retrofit API端点上,忘记了在其中指定subscribeOn(Schedulers.io())。如果将其设置为Retrofit请求的默认调度器,则不需要在每个请求中手动指定subscribeOn(Schedulers.io()),因为它们将默认在后台线程上运行。

问题的原因是在某个Retrofit API端点上忘记了指定subscribeOn(Schedulers.io()),解决方法是在相关的API端点中添加subscribeOn(Schedulers.io()),或者将其设置为Retrofit请求的默认调度器。

0