Rx Android + Модификация callTimeout не запускает onError - PullRequest
0 голосов
/ 30 апреля 2020

Я использую Rx Android + Retrofit для выполнения http-запроса. Код выглядит следующим образом:

Interceptor headerInterceptor = getHeaderInterceptor();
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .callTimeout(5, TimeUnit.SECONDS)
                .addInterceptor(headerInterceptor)
                .addInterceptor(httpLoggingInterceptor)
                .build();

        Gson gson = new GsonBuilder()
                .setLenient()
                .create();

        sRetrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build();

Используйте его так:

ApiProvider.provideApi(MyApi.class)
                .submit(id, mRequest)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        response -> {
                            Log.w("tag", "success");
                        },
                        throwable -> {
                            Log.w("tag", "error");
                        }
                );

Я установил connectTimeout / readTimeout / writeTimeout равным 60 секундам, а callTimeout равным 5 секундам.

Я знаю, что эта конфигурация может быть неправильной, но я просто хочу получить исключение тайм-аута через 5 секунд, и можно вызвать Log.w("tag", "error");.

Однако я обнаружил, что эта строка никогда не будет вызываться для моего тестирования. И если я установлю connectionTimeout на 1 секунду, то эта строка будет вызвана немедленно.

Так что же мне делать, если я хочу, чтобы callTimeout вызывал строку ошибки журнала?

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Что касается того, что я вижу, я думаю, что ваша проблема, возможно, не в том, сколько секунд вы установили для callTimeout(5, TimeUnit.SECONDS), я думаю, что ваш, возможно, поток Rx уже выдал некоторые ошибки, так что поток просто прервал, вы можете получить любой ответ отсюда. Однако вы сбрасываете время секунд до 1 с, а затем перезапускаете приложение, этот поток времени не прерывается, и вы получаете ошибку. Так что просто перепроверьте его еще раз, чтобы убедиться, что ваш поток не будет прерываться даже до входа в эту подписку.

И я был протестирован с некоторыми глупыми реализациями:

class MainActivity : AppCompatActivity() {

    val delayInterceptor = object : Interceptor {
        override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
            Thread.sleep(6000L)
            return chain.proceed(chain.request())
        }

    }
    val client: OkHttpClient = OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .callTimeout(5, TimeUnit.SECONDS)
            .addInterceptor(delayInterceptor)
            .build()

    val retrofit: Retrofit = Retrofit.Builder()
            .baseUrl("https://en.wikipedia.org/")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

    data class Wiki(
            @SerializedName("type")
            val type: String
    )

    interface WikiService {
        @GET("api/rest_v1/page/random/summary")
        fun getRandomSummary(): Single<Wiki>
    }

    @SuppressLint("CheckResult")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        retrofit.create(WikiService::class.java)
                .getRandomSummary()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    Log.d("tag", "success")
                }, {
                    Log.e("tag", "error")
                })
    }
}
0 голосов
/ 08 мая 2020

Я наконец-то нашел причину.

Я использовал com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory, который устарел согласно его readme: https://github.com/JakeWharton/retrofit2-rxjava2-adapter

This is now DEPRECATED!

Retrofit 2.2 and newer have a first-party call adapter for RxJava 2: https://github.com/square/retrofit/tree/master/retrofit-adapters/rxjava2

После переключаясь на retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory, все начинает хорошо работать.

И кстати, для любого парня, который может быть заинтересован в том, какие различия между ними двумя? Прикрепите ключевую информацию, которую я нашел ниже:

enter image description here

...