web-dev-qa-db-ja.com

Retrofit API呼び出しは「HTTP FAILED:Java.io.IOException:Canceled」を受け取ります

なぜこれが起こっているのか分かりません。 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
22
oleg.v

ユーザーがリクエストをキャンセルすると、その例外がスローされます。 RxJavaCallAdapterFactoryを使用する場合、呼び出しが完了する前にサブスクリプションのサブスクリプションが解除されると、これが発生します。したがって、呼び出しを行った後のある時点で、subscription.unsubscribe()を実行すると、基になるリクエストがキャンセルされます。

50
Kiskae

@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
 */
0
luckyhandler