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
}
}
}
}