Retrofit API调用收到"HTTP FAILED: java.io.IOException: Canceled"错误信息

46

不知道为什么会发生这种情况。我的调用没有触发任何一个rx回调(onCompleted(), onError(), onNext())。我收到的唯一信息是这个okhttp输出:

无法弄清楚为什么会发生这种情况。我的调用没有触发任何一个rx回调(onCompleted()、onError()、onNext())。我只收到了这个OkHttp输出:

D/OkHttp: --> GET https://api.privatbank.ua/p24api/exchange_rates?json=true&date=20.11.2016 http/1.1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled

适配器模块:

@Module
public class RestModule {

    @Provides
    @Singleton
    public HttpLoggingInterceptor providesHttpLogginInterceptor() {
        return new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
    }

    @Provides
    @Singleton
    public OkHttpClient providesOkHttpClient(@NonNull HttpLoggingInterceptor loggingInterceptor) {
        return new OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .connectTimeout(ConstantsManager.CONNECTION_TIME_OUT, TimeUnit.SECONDS)
            .readTimeout(ConstantsManager.READ_TIME_OUT, TimeUnit.SECONDS)
            .build();
    }

    @Provides
    @Singleton
    public Gson providesGson() {
        return new GsonBuilder().create();
    }

    @Provides
    @Singleton
    public Retrofit providesRetrofit(@NonNull OkHttpClient okHttpClient, @NonNull Gson gson) {
        return new Retrofit.Builder()
            .baseUrl(ConstantsManager.BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
    }

    @Provides
    @Singleton
    public PrivatbankApi providesPrivatbankApi(@NonNull Retrofit retrofit) {
        return retrofit.create(PrivatbankApi.class);
    }
}

API接口:

public interface PrivatbankApi {

    @GET
    Observable<CurrentRates> loadCurrentRates(@NonNull @Url String url);

    @GET("exchange_rates")
    Observable<DateRates> loadDateRates(@NonNull @Query("json") Boolean json, @NonNull @Query("date") String date);

}

订阅:

subscription = dataManager.loadDateRates(date)
                .subscribeOn(Schedulers.io())
                .doAfterTerminate(() -> {
                })
                .subscribe(dateRates -> {
                    // My code here...
                }, throwable -> {
                    Timber.e(throwable, "Error while loading data occurred!");
                });

顺便提一句,这两个调用都会得到相同的错误:

D/OkHttp: --> GET https://privat24.privatbank.ua/p24/accountorder?oper=prp&PUREXML&apicour&country=ua http/1.1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled
D/OkHttp: --> GET https://api.privatbank.ua/p24api/exchange_rates?json=true&date=20.11.2016 http/1.1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled

请参见 https://dev59.com/e1IH5IYBdhLWcg3wB4B7#69715645。 - CoolMind
5个回答

75

当用户取消请求时,会抛出该异常。使用 RxJavaCallAdapterFactory 时,如果订阅在调用完成之前取消,则会出现这种情况。因此,我猜想在调用之后的某个时间点,您执行了 subscription.unsubscribe(),从而取消了底层请求。


5
当我将代码移到 intent service 类的 onDestroy 方法中并调用 disposable.dispose() 时,我遇到了同样的问题。请你翻译此内容。 - Kiran Benny Joseph
2
各位,subscription.unsubscribe() 应该在哪里调用?我遇到了同样的问题。 - Harshad07
2
我在 onDestroy 中调用了 disposable.dispose(),但是当我退出后再次回到该页面时,OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled 再次出现。有人能帮我解决这个问题吗? - Lester L.

1
我有同样的问题,但在我的情况下,当两个请求订阅相同的CompositeDisposable时,其中一个会被取消。我的意思是这两个请求是并行执行的。 我的解决方案:我只定义了两个不同的订阅通道。

1

对我有帮助的是替换已弃用的调用适配器:

implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

使用:

implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'

这个帮助了我解决了这个问题,现在每次都会调用onError()。 更多信息请参考:https://github.com/JakeWharton/retrofit2-rxjava2-adapter


它救了我的一天 :) 谢谢 再举一个例子来保持依赖项最新。 - mr.kostua

0

0
感谢 @Kiskae。这给了我正确的提示。在我的情况下,我使用了一个CompositeSubscription,并在它被另一个方法取消订阅后添加了一个订阅。
/**
 * Adds a new {@link Subscription} to this {@code CompositeSubscription} if the
 * {@code CompositeSubscription} is not yet unsubscribed. If the {@code CompositeSubscription} <em>is</em>
 * unsubscribed, {@code add} will indicate this by explicitly unsubscribing the new {@code Subscription} as
 * well.
 *
 * @param s
 *         the {@link Subscription} to add
 */

嗨,我应该把subscription.unsubscribe()放在哪里?我遇到了同样的问题。 - Harshad07
在你的类中作为属性/全局变量持有的CompositeSubscription上。 - luckyhandler
remote.getContactDetails(contactId) .performOnBackOutOnMain(scheduler) .subscribe({ data -> mContactResponse.success(data) },{ error -> mContactResponse.failed(error) }) .addTo(compositeDisposable)我是这样进行远程调用的。 - Harshad07
我之前是在使用 RxJava 1,这似乎是与 RxJava 2 相关的。但我猜可能是在使用 compositeDisposable 前有一些未取消订阅的内容。 - luckyhandler
我马上会发布我的代码,请您稍等一下看看。 - Harshad07
请检查此代码:https://stackoverflow.com/questions/50739281/http-failed-java-net-socketexception-socket-closed-retrofit?noredirect=1#comment88486176_50739281 - Harshad07

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接