RxAndroid + Retrofit callTimeout不触发onError。

问题描述 投票:0回答:1

我使用RxAndroid + 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触发日志错误行,我应该怎么做?

android retrofit rx-java okhttp rx-android
1个回答
1
投票

在我看来,我想你的问题可能不是来自于你为你的 callTimeout(5, TimeUnit.SECONDS)我想你可能Rx流已经抛出了一些错误,所以流只是打破你可以从这里得到任何响应。然而,你重新设置时间秒数为1s,然后你重新启动应用程序,这一次流不破,你得到错误。所以简单的重新测试一遍,以确保你的流不会打破,甚至在进入这个订阅。

我一直在测试一些愚蠢的实现。

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
投票

我终于找到了原因

我使用的是 com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory,根据其readme已经被废弃。https:/github.comJakeWhartonretrofit2-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

© www.soinside.com 2019 - 2024. All rights reserved.