应用程序崩溃,出现java.net.SocketTimeoutException: timeout错误(Kotlin, Retrofit)

8

如果响应未到达,应用程序将在此行崩溃。

chain.proceed(requestBuilder.build())

这里是我的Retrofit客户端类

class RetrofitClient {

    private val apiService: ApiServiceInterface

    init {
        val builder = Retrofit.Builder()
        builder.baseUrl(RequestParameters.BASE_URL)
        builder.addConverterFactory(GsonConverterFactory.create())
        builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//added for adapter
        builder.client(getClient())
        val retrofit = builder.build()
        apiService = retrofit.create(ApiServiceInterface::class.java)
    }

    companion object {
        private var clientInstance: RetrofitClient? = null
        lateinit var context: Context

        fun getInstance(): RetrofitClient {
            if (clientInstance == null) {
                clientInstance = RetrofitClient()
            }
            return clientInstance as RetrofitClient
        }
    }

    fun getApiInterface(): ApiServiceInterface {
        return apiService
    }

    private fun getClient(): OkHttpClient {

        val httpClient = OkHttpClient.Builder()
        httpClient.readTimeout(25, TimeUnit.SECONDS)
        httpClient.connectTimeout(25, TimeUnit.SECONDS)

        httpClient.addInterceptor { chain ->
            val original = chain.request()

            val requestBuilder = original.newBuilder()
                    .header(RequestParameters.X_API, RequestParameters.H_XAPI_KEY)
                    .method(original.method(), original.body())

            chain.proceed(requestBuilder.build())
        }

        // set your desired log level
        val logging = HttpLoggingInterceptor()
        logging.level = HttpLoggingInterceptor.Level.HEADERS
        logging.level = HttpLoggingInterceptor.Level.BODY
        httpClient.addInterceptor(logging)

        return httpClient.build()
    }
}

以下是日志中的错误内容:

1542609097.397 26572-26572/com.app.mylife W/System.err: java.net.SocketTimeoutException: timeout
1542609097.397 26572-26572/com.app.mylife W/System.err:     at okio.Okio$4.newTimeoutException(Okio.java:230)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okio.AsyncTimeout.exit(AsyncTimeout.java:285)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okio.AsyncTimeout$2.read(AsyncTimeout.java:241)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okio.RealBufferedSource.indexOf(RealBufferedSource.java:345)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:217)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:212)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:125)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
1542609097.398 26572-26572/com.app.mylife W/System.err:     at com.app.mylife.retrofit.RetrofitClient$getClient$1.intercept(RetrofitClient.kt:64)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at okhttp3.RealCall.execute(RealCall.java:77)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:10179)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:10179)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$1.run(ObservableSubscribeOn.java:39)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at io.reactivex.Scheduler$1.run(Scheduler.java:134)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:59)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at java.lang.Thread.run(Thread.java:764)
1542609097.399 26572-26572/com.app.mylife W/System.err: Caused by: java.net.SocketException: Socket closed
1542609097.399 26572-26572/com.app.mylife W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:203)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:139)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at okio.Okio$2.read(Okio.java:139)
1542609097.399 26572-26572/com.app.mylife W/System.err:     at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
1542609097.400 26572-26572/com.app.mylife W/System.err:     ... 39 more

你能解决这个问题吗? - keshav kowshik
最终我通过 这个 解决了这个问题,如果你正在使用 Corouine + Kotlin。 - Kishan Solanki
2个回答

0

尝试这个代码方式..创建Retrofit对象的部分。

class ApiClient {

companion object {
    val BASE_URL = "https://simplifiedcoding.net/demos/"
    var retrofit: Retrofit? = null
    fun getClient(): Retrofit? {
        if (retrofit == null) {
            val interceptor = HttpLoggingInterceptor()
            interceptor.level = HttpLoggingInterceptor.Level.BODY
            val client = OkHttpClient.Builder().apply {
            readTimeout(20, TimeUnit.SECONDS)
            writeTimeout(20, TimeUnit.SECONDS)
            connectTimeout(20, TimeUnit.SECONDS)
            addInterceptor(interceptor)
            addInterceptor { chain ->
                var request = chain.request()
                request = request.newBuilder()
                        .build()
                val response = chain.proceed(request)
                response
            }
            }
            retrofit = Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(client.build())

                    .addConverterFactory(GsonConverterFactory.create())
                    .build()

        }

        return retrofit
    }
}

}

创建用于调用 API 的接口。
interface ApiInterface {
@GET("marvel")
fun getData(): Call<List<Hero>>

}

在名为api的活动或片段中,我希望您创建响应pojo类。
var apiInterface: ApiInterface = ApiClient.getClient()!!.create(ApiInterface::class.java)
    var hero: Call<List<Hero>>
    hero = apiInterface.getData()
    hero.enqueue(object : Callback<List<Hero>> {
        override fun onFailure(call: Call<List<Hero>>?, t: Throwable?) {
            closeDialog(dialog)
            Toast.makeText(mContext, t?.message, Toast.LENGTH_SHORT).show()
            Log.d("Error:::",t?.message)
        }

        override fun onResponse(call: Call<List<Hero>>?, response: Response<List<Hero>>?) {
           mHeroDataList.clear()
            if (response != null && response.isSuccessful && response.body() != null) {
                closeDialog(dialog)
                mHeroDataList .addAll(response.body()!!)
                setAdapter(mHeroDataList)
            }
        }

    })

这并没有帮助,因为它和我写的代码是一样的。 - Kishan Solanki
1
增加超时时间值。 - user4571931
10
问题是如果响应在超时时间内没有到达,应用程序会崩溃。我们该如何处理这个问题?我的担忧是,如果响应没有到达(无论是30秒还是60秒),应用程序不应该崩溃。增加超时值并不是一个理想的解决方案。 - Kishan Solanki

0

当没有网络时,此代码会抛出异常。因此,您可以使用try和catch块捕获异常。您可以在调用网络的位置放置try和catch。这样就不会再次崩溃您的应用程序。


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