Okhttp超时时间设置和相关问题解决


okhttp超时相关问题


  • 设置了超时时间,但是超时时间还是很长,因为在DNS异常处理时花费了大量时间,我们需要给DNS解析设置超时时间
  • UnknownHostException异常处理
  • 日志拦截器打印请求和回传消息

超时时间设置


//okhttp3超时时间设置
mOkHttpClient = OkHttpClient.Builder()
                    .retryOnConnectionFailure(false)//取消重试
                    .addInterceptor(OkHttpLogInterceptor())//日志拦截器
                    .dns(OkHttpDns(3L))
                    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)//设置连接超时时间
                    .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                    .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                    .build()

日志拦截器


import com.tencent.wecast.utils.Logger
import java.io.IOException
import java.nio.charset.Charset
import java.nio.charset.UnsupportedCharsetException
import java.util.concurrent.TimeUnit
import okhttp3.Interceptor
import okhttp3.Response
import okio.Buffer


/**
 * okhttp 拦截器
 */

class OkHttpLogInterceptor : Interceptor {
    companion object {
        private const val TAG = "OkHttpLogInterceptor"
        private val UTF8 = Charset.forName("UTF-8")
    }


    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val requestBody = request.body
        var body: String? = null
        if (requestBody != null) {
            val buffer = Buffer()
            requestBody.writeTo(buffer)
            var charset: Charset? = UTF8
            val contentType = requestBody.contentType()
            if (contentType != null) {
                charset = contentType.charset(UTF8)
            }
            body = buffer.readString(charset!!)
        }

        Logger.t(TAG).d(
                "Send: method:" + request.method
                        + "\nurl:" + request.url
                        + "\nHeader:" + request.headers
                        + "\nParams: " + body)

        val startNs = System.nanoTime()
        val response = chain.proceed(request)
        val tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs)

        val responseBody = response.body
        val rBody: String

        val source = responseBody!!.source()
        source.request(java.lang.Long.MAX_VALUE)
        val buffer = source.buffer()

        var charset: Charset? = UTF8
        val contentType = responseBody.contentType()
        if (contentType != null) {
            try {
                charset = contentType.charset(UTF8)
            } catch (e: UnsupportedCharsetException) {
                e.printStackTrace()
            }

        }
        rBody = buffer.clone().readString(charset!!)

        Logger.t(TAG).d(
                ("Receiver: code:" + response.code
                        + "\nurl:" + response.request.url
                        + "\nbody:" + body
                        + "\nResponse: " + rBody))

        return response
    }
}


java.net.UnknownHostException异常


解决办法:(1)添加以下网络相关权限 (2)设置DNS解析异常处理

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />

DNS解析异常拦截


import okhttp3.Dns
import java.net.InetAddress
import java.net.UnknownHostException
import java.util.concurrent.Callable
import java.util.concurrent.FutureTask
import java.util.concurrent.TimeUnit

class OkHttpDns constructor(private val timeout:Long):Dns {

    override fun lookup(hostname: String): List<InetAddress> {
        return if (hostname == null) {
            throw UnknownHostException("hostname == null")
        } else {
            try {
                val task = FutureTask(
                        Callable { listOf(*InetAddress.getAllByName(hostname)) })
                Thread(task).start()
                task.get(timeout, TimeUnit.SECONDS)
            } catch (var4: Exception) {
                val unknownHostException = UnknownHostException("Broken system behaviour for dns lookup of $hostname")
                unknownHostException.initCause(var4)
                throw unknownHostException
            }

        }
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这可能是因为第二个`OkHttp`连接在等待第一个连接完成时,已经达到了默认的连接超时时间(10秒)。解决问题的方法之一是将`OkHttp`连接的超时时间设置得更长。你可以在构建`OkHttpClient`时设置超时时间,如下所示: ```java OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间为30秒 .readTimeout(30, TimeUnit.SECONDS) // 设置读取超时时间为30秒 .writeTimeout(30, TimeUnit.SECONDS) // 设置写入超时时间为30秒 .build(); ``` 另外,你也可以将`OkHttpClient`实例化为单例模式,这样可以避免频繁地创建和销毁连接,提高性能并减少超时问题的出现。 ### 回答2: 当一个页面同时使用2个okhttp3连接远程服务器时,第二个出现超时问题可能是由于以下原因导致的: 1. 连接池限制:okhttp3默认使用连接池来管理HTTP连接,连接池有默认的最大连接数限制。当第一个请求占用了所有的连接,第二个请求就无法获取到可用连接导致超时。可以通过增加连接池的最大连接数来解决这个问题。 2. 网络状况:第一个请求可能耗时较长或者存在网络故障,导致第二个请求在超时时间内无法建立连接。可以通过增加超时时间或者优化网络状况来解决这个问题。 3. 服务器处理能力:第一个请求占用了服务器的处理资源,导致服务器无法及时响应第二个请求。可以优化服务器的处理能力,例如增加服务器的性能或者优化代码逻辑。 解决这个问题的方法如下: 1. 调整连接池大小:通过调整okhttp3的连接池大小,增加最大连接数,确保在同时发起多个请求时不会出现连接不足的情况。 ```java // 创建OkHttpClient时设置连接池大小 ConnectionPool connectionPool = new ConnectionPool(10, 5, TimeUnit.MINUTES); OkHttpClient client = new OkHttpClient.Builder() .connectionPool(connectionPool) .build(); ``` 2. 调整超时时间:通过增加连接和读取超时时间,确保在网络不稳定或者服务器响应较慢时,仍然能够完成请求。 ```java // 创建OkHttpClient时设置超时时间 OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS) .build(); ``` 3. 优化服务器处理能力:对于服务器处理能力有限的情况,可以通过优化服务器的代码逻辑,增加服务器的性能或者增加机器来提升处理能力。 综上所述,同时使用2个okhttp3连接远程服务器时,第二个出现超时问题可能是由于连接池限制、网络状况或服务器处理能力等原因导致的。可以通过调整连接池大小、超时时间或者优化服务器处理能力来解决这个问题。 ### 回答3: 在Android中同时使用两个OkHttp3连接远程服务器时,第二个出现超时问题可能有以下几个原因: 1. 连接池限制:OkHttp默认使用连接池来管理连接,限制了每个主机最大的连接数。如果第一个请求占用了连接池中的所有连接,第二个请求就无法获取到连接而超时。可以通过调整连接池的大小来解决这个问题,使用`ConnectionPool()`构造函数设置合适的参数。 2. 连接超时设置不合理:OkHttp默认的连接超时时间是10秒,即在10秒内无法建立连接就会超时。如果网络环境较差或服务器响应较慢,可能导致第二个请求在连接时已经超过了默认的连接超时时间。可以通过设置连接超时时间解决这个问题,使用`connectTimeout()`方法设置合理的时间,例如20秒。 3. 服务器处理速度慢:如果第一个请求需要较长时间才能处理完毕,会导致第二个请求等待的时间过长,超过了默认的读取超时时间。可以通过设置读取超时时间解决这个问题,使用`readTimeout()`方法设置合适的时间解决方法: 1. 调整连接池大小:使用`ConnectionPool()`构造函数设置合适的参数,增加连接池的大小,确保足够的连接供两个请求使用。 2. 调整连接超时时间:使用`connectTimeout()`方法设置合适的连接超时时间,确保在网络或服务器响应较慢的情况下,仍能在合理的时间内建立连接。 3. 调整读取超时时间:使用`readTimeout()`方法设置合适的读取超时时间,确保即使第一个请求处理较慢,第二个请求也不会因为等待时间过长而超时。 综上所述,调整连接池大小、连接超时时间和读取超时时间可以解决Android中同时使用两个OkHttp3连接远程服务器时第二个请求超时问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值