android ok,Android OKHttp的基本使用

一、

Android中网络请求是必不可少的。OkHttp是网络框架界的大佬了,很多网络框架都基于OkHttp封装。本章主要讲OKHttp的使用,后面会写到用它封装的其他框架的使用。

需在 build.gradle 里面加入依赖

implementation 'com.squareup.okhttp3:okhttp:4.3.1'

二、

由于网络请求是耗时操作,在UI线程中,请求超过5s会导致应用无响应(ANR),所以Android规定了网络请求只能在子线程里面完成。

同步请求和异步请求

在Http中,请求的方式有两种:GET 和 POST。请求分为同步请求和异步请求。GET 和 POST 的差别在于有无请求体。先来看看同步和异步的区别。(以GET请求为例)

① 同步网络请求:需要在子线程中执行,而处理的UI需要回到UI线程中处理。

private fun getSyncOkHttp() {

//子线程

thread {

//请求参数

val request = Request.Builder()

.url("http://www.baidu.com")

.build()

//客户端

val client = OkHttpClient.Builder()

.build()

//调用execute()为同步请求并返回Response对象

response = client.newCall(request).execute()

//判断时候请求成功

response?.isSuccessful?.apply {

if (this) {

runOnUiThread {

text1.text = response?.message

}

}

}

}

}

同步网络请求的标志:execute()。假如得到结果后要对UI进行操作,需要切换到主线程。

② 异步网络请求:不需要在子线程了,但回调方法是执行在子线程中,所以在更新UI时还要跳转到UI线程中,跟同步请求切换线程一样。

private fun getAsyncOkHttp() {

//请求参数

val request = Request.Builder()

.url("http://www.baidu.com")

.build()

//客户端

val client = OkHttpClient.Builder()

.build()

//调用enqueue()为异步请求并回调到子线程

client.newCall(request).enqueue(object : Callback {

override fun onFailure(call: Call, e: IOException) {

}

//请求成功

override fun onResponse(call: Call, response: Response) {

//切换到UI线程

runOnUiThread {

text1.text = response.message

}

}

})

}

异步网络请求的标志:enqueue()。假如得到结果后要对UI进行操作,需要切换到主线程。

首先,我们要建立一个客户端client,用于发送请求参数request,再把所需要的数据添加到request,如url、请求头header...,然后用client调用newCall方法,把请求参数传进去,最后调用execute()或者enqueue()得到回调结果并做一系列处理。

再来看下POST请求(以异步请求为例):

private fun postAsyncOkHttp() {

//请求体(传输表单类型)

val mBody = FormBody.Builder()

.build()

//请求参数

val request = Request.Builder()

.url("http://www.baidu.com")

.post(mBody)

.build()

//客户端

val client = OkHttpClient.Builder()

.build()

client.newCall(request).enqueue(object : Callback {

override fun onFailure(call: Call, e: IOException) {

}

override fun onResponse(call: Call, response: Response) {

runOnUiThread {

text1.text = response.message

}

}

})

}

与GET方式不同的是,要在请求参数里面加个请求体,request里面用post()接受一个RequestBody对象,RequestBody是一个抽象类,分别有FormBody和MultipartBody两个子类,上面这个例子使用的是FormBody,用于传输表单类型的参数。MultipartBody则支持多类型的参数传递,例如:在传输表单类型的参数的同时,还是可以传输文件。创建一个MultipartBody对象再调用post()方法就OK了。

在Request.Builder中如果调用post方法则把请求方式设为POST,否则默认为GET。与GET相比,POST需要有请求体接收,其他都与GET相同。

请求头

刚才有提到请求头Header,它是通过Request.Builder对象的相关方法来维护的,如下:

① headers(Headers headers)

② header(String name, String value)

③ addHeader(String name, String value)

④ removeHeader(String name)

addHeader和removeHeader方法,分别是添加和移除header信息。header(String name, String value)这是会重新设置指定name的header信息。headers(Headers headers)则是会移除掉原有的所有header信息,将参数headers的header信息添加到请求中。

注:header和addHeader的区别:指定name如果存在的话,那么header会重新设定name的value,如果不存在,header和addHeader一样是添加头信息。

//请求参数

val request = Request.Builder()

.addHeader("Charset","UTF-8")

.url("http://www.baidu.com")

.build()

超时时间

在网络请求的客户端中,我们可以设定请求的超时时间,包括连接,调用和读写时间,在OKHttpClient.Builder里面设定的,假如不设定,将使用默认的超时设置。

val timeOut:Long = 15 //超时时间

//客户端

val client = OkHttpClient.Builder()

.connectTimeout(timeOut, TimeUnit.SECONDS)

.readTimeout(timeOut, TimeUnit.SECONDS)

.writeTimeout(timeOut, TimeUnit.SECONDS)

.build()

其中第一个参数是超时时间,第二个参数是超时时间单位。

拦截器(Interceptor)

拦截器在OKHttp里面的作用还是非常强大的,能够监视请求,例如在拦截器中设定请求发送和响应的一些信息输出操作,还可以重写请求信息,例如修改url、添加请求头header...

拦截器还分为两种:

① 网络拦截器

② 应用拦截器

首先创建个拦截器继承Interceptor接口,复写Intercept方法。其中,chain可以去到你想要的数据,例如chain.request()能去到当前的请求体,chain.url能去到当前的url...就是说,请求经过一系列操作后来到拦截器,拦截器能得到请求的东西并能对其进行操作,最后调用chain.proceed()方法把响应结果返回出去。

private fun getAsyncOkHttp() {

//请求参数

val request = Request.Builder()

.url("http://www.baidu.com")

.build()

//客户端

val client = OkHttpClient.Builder()

.addInterceptor(MyInterceptor())

.build()

//调用enqueue()为异步请求并回调到子线程

client.newCall(request).enqueue(object : Callback {

override fun onFailure(call: Call, e: IOException) {

}

//请求成功

override fun onResponse(call: Call, response: Response) {

//切换到UI线程

runOnUiThread {

Log.e("Interceptor",response.url.toString())

}

}

})

}

private class MyInterceptor:Interceptor{

override fun intercept(chain: Interceptor.Chain): Response {

val oldRequest = chain.request()

val newRequest = oldRequest.newBuilder()

.url("http://www.google.com")

.build()

return chain.proceed(newRequest)

}

}

在原来的client中添加了拦截器,拦截器中先去到原来的请求体,得到oldRequest,再调用newBuilder()方法对其进行重构,可以加一些请求头信息,或者更改url...之后把定义好的newRequest通过chain.proceed()得到新的response返回出去。其中,chain.proceed()是真正发生网络请求的地方。运行结果打印出之后设定的url:"http://www.google.com"

注:拦截器可以设置多个,并且拦截器的调用是有顺序的。例如进去A拦截器出来后,再进入B拦截器时,请求体与刚进去A拦截器是有所不同的。

之前还写过一篇用拦截器更改baseUrl的操作的文章,感兴趣的同学可以看看。

三、

OKHttp的使用基本就这些了,如果想更加深入可以看看源码,学习时请求顺序不要乱就好了,记得请求头、超时时间设置及拦截器分别再那些地方加上去,初学者很容易混淆的,包括我 - -!

后面会继续写OKHttp+Retrofit的配合使用。文章有写的不好的地方麻烦大伙提出来,感谢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值