OkHttp3的简单使用
OkHttp是目前最流行的网络请求框架,几乎现在的Android开发中都是使用OkHttp来进行网络请求的,搭配Retrofit使用的话更方便了。本篇文章即是记录OkHttp的一些基本使用方式,方便以后回忆和查询。
引入依赖
1 | |
这里同时引入了OkHttp和Logging库,因此使用了okhttp-bom去统一管理依赖版本。正常情况下只需要引入implementation("com.squareup.okhttp3:okhttp:4.12.0")即可。另外就是需要加上网络权限。
1 | |
简单的网络请求
1 | |
首先创建一个Request对象,这是请求的主体,整个请求的参数以及方式等都是由Request去声明的。然后开了一个线程进行网络请求,因为OkHttp是禁止在主线程中进行同步方式的网络请求,因为请求过程是一个耗时操作,会阻塞主线程。然后就是创建了一个OkHttpClient,它是网络请求的一个工厂类转换类。请求的对象Request会被OkHttpClient转换成不同的Call的实现类,最终由Call以同步或者异步的方式来执行网络请求。
OkHttpClient
在上面的简单的网络请求实例中可以看到,OkHttpClient用来处理Request请求的。实际上它是一个通用的配置类,可以用来配置整个网络请求的属性。如缓存、连接池、线程池、Cookie等等,因此在开发中应该将其设计成单例的形式供各个功能模块进行调用。
OkHttpClient采用了Builder模式设计,可以进行各种自定义的操作设置。实际上各种默认的设置已经能够满足大部分的需求了,需要自定义的部分反而不多,更多的是添加Interceptor。如我们上面的加的Logging的依赖即是一个拦截器,可以添加在OkHttpClient中用于请求参数的打印。
1 | |
由于默认的Logging的Level是NONE,什么都不会输出,因此需要将其设置为其他可输出的级别,这里设置的是BODY级别,会输出所有的请求内容。
Request
Request是用来构建网络请求的,采用的Builder模式来构建一个请求,默认是GET的请求方式。对于常用的HTTP请求方法都是支持的,如GET、POST、HEAD、PUT等。
1 | |
GET的请求方式比较简单,需要传递参数的话也是直接通过url中拼接参数。而POST通常不会在url中拼接参数,而是使用别的方式。对应在Request中,当选择POST方式时,必须传递一个非空的RequestBody参数用于存放请求参数。常用的如表单类型:则需要传递的是FormBody。
1 | |
简单表单格式,会在请求头中添加Content-Type: application/x-www-form-urlencoded。这种类型通常都是基础的字符串参数,如果想要传递文件等信息的话,则需要用到MultipartBody,可以支持各种参数类型。
1 | |
MultipartBody实际产生的内容类型是混合类型,Content-Type: multipart/mixed; boundary=d721ad8b-8e88-4fcf-b370-91b2a43aa50c,会将请求内容分为多个部分,每个部分使用boundary的值来进行区分。上面的实例中,添加了一个表单类型的部分和一个文件内容的部分。至于其他的请求方式如PUT、HEAD等,与上面的也是一样的。
Call
Call是网络请求中的进一步实现,具体的实现是RealCall,最终的请求即是由Call发起的。它有两种请求方式,同步方式和异步方式。注意不要在主线程中调用同步方式的请求。
1 | |
Response
Response是网络请求的结果,可以通过code获取结果码来判断请求是否成功,然后通过Response.body获取到请求结果。正常来说直接通过body.string()即可获取到此次的请求结果。当然,如果是下载的话,则可以通过body.byteStream()获取到此次连接的数据流,然后通过读取stream来实现下载和计算进度。
Interceptor
OkHttp的整体网络请求是使用的责任链模式实现的,主体是五大拦截器,逐渐细化对网络请求参数的拆解、封装、压缩、传输等。在此基础上,也允许我们添加自定义的拦截器去参与到网络请求的过程中。如前面引入的HttpLoggingInterceptor就是一个用于打印请求参数和结果的拦截器。
1 | |
拦截器主要是在OkHttpClient构建的时候添加进去的,我们在正常使用的时候,传入自定义的Interceptor参数,然后在intercept方法中去处理自己的逻辑。如我们想在每次请求前和请求后打印出HEAD信息 :
1 | |
总结
网络请求无非是建立连接,发送请求,处理响应三个步骤。对于我们使用来说,只需要关注发送请求和处理响应即可。发送请求主要是构建Request,通过Request的构建时调用的不同方法去选择使用什么方式进行请求,以及参数的传入、HEAD的添加等。而像Cookie的添加,则是在构建OkHttpClient的时候传入的CookieJar来管理Cookie。每次请求的时候,都会根据url从CookieJar中取出对应的Cookie写入到请求头中,然后在收到响应后将响应头中的Cookie存储到CookieJar。
响应则更简单,主要是从Response中取出数据。可以从Response中获取到状态码来判断网络请求是否成功,最主要的是获取body信息,这是一次网络请求的主体,通常是使用Json格式的数据,然后我们将其序列化成对象进行使用即可,其余皆不需要关注。
由于OkHttp良好的封装和设计模式的应用,使得我们在使用的时候异常简单,几乎不需要什么学习成本即可完成网络请求。这么好的库不学习一番太过浪费了,后面将对OkHttp的源码进行分析,剖析它的设计之美。
