OkHttp讲义
OkHttp 使⽤⽅法简介
创建⼀个
OkHttp的实例1
OkHttpClient client = new OkHttpClient.Builder().build();
创建
Request1
2
3Request request = new Request.Builder()
.url("http://hencoder.com")
.build();创建
Call并发起⽹络请求1
2
3
4
5
6
7
8
9
10client.newCall(request).enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
}
public void onResponse(Call call, Response response) throws IOException{
Log.d("okhttp response", response.body().string());
}
});enqueue: 异步的
excute: 同步的
OkHttp 源码总结
OkHttpClient相当于配置中⼼,所有的请求都会共享这些配置(例如出错是否重试、共享的连接池)。OkHttpClient中的配置主要有:Dispatcher dispatcher:调度器,⽤于调度后台发起的⽹络请求,有后台总请求数和单主机总请求数的控制。List<Protocol> protocols:⽀持的应⽤层协议,即HTTP/1.1、HTTP/2等。List<ConnectionSpec> connectionSpecs:应⽤层⽀持的Socket设置,即使⽤明⽂传输(⽤于HTTP)还是某个版本的TLS(⽤于HTTPS)。其中的clearText(“明文”没有用加密)等同于httpList<Interceptor> interceptors:⼤多数时候使⽤的Interceptor都应该配置到这⾥。List<Interceptor> networkInterceptors:直接和⽹络请求交互的Interceptor配置到这⾥,例如如果你想查看返回的301报⽂或者未解压的Response Body,需要在这⾥看。CookieJar cookieJar(饼干存储罐):管理Cookie的控制器。OkHttp提供了Cookie存取的判断⽀持(即什么时候需要存Cookie,什么时候需要读取Cookie,但没有给出具体的存取实现。
如果需要存取Cookie,你得⾃⼰写实现,例如⽤Map存在内存⾥,或者⽤别的⽅式存在本地存储或者数据库。Cache cache:Cache存储的配置。默认是没有,如果需要⽤,得⾃⼰配置出Cache存储的⽂件位置以及存储空间上限。HostnameVerifier hostnameVerifier:⽤于验证HTTPS握⼿过程中下载到的证书所属者是否和⾃⼰要访问的主机名⼀致。- sokect是tcp的端口(http是没有端口一说)
CertificatePinner certificatePinner:⽤于设置HTTPS握⼿过程中针对某个Host的Certifificate Public Key Pinner,即把⽹站证书链中的每⼀个证书公钥直接拿来提前配置进OkHttpClient⾥去,以跳过本地根证书,直接从代码⾥进⾏认证。这种⽤法⽐较少⻅,⼀般⽤于防⽌⽹站证书被⼈仿制。Authenticator authenticator:⽤于⾃动重新认证。配置之后,在请求收到401(权限不足)状态码的响应是,会直接调⽤authenticator,⼿动加⼊Authorization header之后⾃动重新发起请求。boolean followRedirects:遇到重定向的要求是,是否⾃动follow。boolean followSslRedirects在重定向时,如果原先请求的是http⽽重定向的⽬标是https,或者原先请求的是https⽽重定向的⽬标是http,是否依然⾃动follow。(记得,不是「是否⾃动follow HTTPS URL重定向的意思,⽽是是否⾃动follow在HTTP和HTTPS之间切换的重定向)boolean retryOnConnectionFailure:在请求失败的时候是否⾃动重试。注意,⼤多数的请求失败并不属于OkHttp所定义的「需要重试」,这种重试只适⽤于「同⼀个域名的多个IP切换重试」「Socket失效重试」等情况。int connectTimeout:建⽴连接(TCP或TLS)的超时时间。int readTimeout:发起请求到读到响应数据的超时时间。int writeTimeout:发起请求并被⽬标服务器接受的超时时间。(为什么?因为有时候对⽅服务器可能由于某种原因⽽不读取你的Request)
newCall(Request)⽅法会返回⼀个RealCall对象,它是Call接⼝的实现。当调⽤RealCall.execute()的时候,RealCall.getResponseWithInterceptorChain()会被调⽤,它会发起⽹络请求并拿到返回的响应,装进⼀个Response对象并作为返回值返回;RealCall.enqueue()被调⽤的时候⼤同⼩异,区别在于enqueue()会使⽤Dispatcher的线程池来把请求放在后台线程进⾏,但实质上使⽤的同样也是getResponseWithInterceptorChain()⽅法。getResponseWithInterceptorChain()⽅法做的事:把所有配置好的Interceptor放在⼀个List⾥,然后作为参数,创建⼀个RealInterceptorChain对象,并调⽤chain.proceed(request)来发起请求和获取响应。在
RealInterceptorChain中,多个Interceptor会依次调⽤⾃⼰的intercept()⽅法。这个⽅法会做三件事:- 对请求进⾏预处理
- 预处理之后,重新调⽤
RealIntercepterChain.proceed()把请求交给下⼀个Interceptor - 在下⼀个
Interceptor处理完成并返回之后,拿到 Response 进⾏后续处理
当然了,最后⼀个 Interceptor 的任务只有⼀个:做真正的⽹络请求并拿到响应
从上到下,每级
Interceptor做的事:- ⾸先是开发者使⽤
addInterceptor(Interceptor)所设置的,它们会按照开发者的要求,在所有其他Interceptor处理之前,进⾏最早的预处理⼯作,以及在收到Response之后,做最后的善后⼯作。如果你有统⼀的header要添加,可以在这⾥设置; - 然后是
RetryAndFollowUpInterceptor:它负责在请求失败时的重试,以及重定向的⾃动后续请求。它的存在,可以让重试和重定向对于开发者是⽆感知的; BridgeInterceptor:它负责⼀些不影响开发者开发,但影响HTTP交互的⼀些额外预处理。例如,Content-Length的计算和添加、gzip的⽀持(Accept-Encoding: gzip)、gzip压缩数据的解包,都是发⽣在这⾥;CacheInterceptor:它负责Cache的处理。把它放在后⾯的⽹络交互相关Interceptor的前⾯的好处是,如果本地有了可⽤的Cache,⼀个请求可以在没有发⽣实质⽹络交互的情况下就返回缓存结果,⽽完全不需要开发者做出任何的额外⼯作,让Cache更加⽆感知;ConnectInterceptor:它负责建⽴连接。在这⾥,OkHttp会创建出⽹络请求所需要的TCP连接(如果是HTTP),或者是建⽴在TCP连接之上的TLS连接(如果是HTTPS),并且会创建出对应的HttpCodec对象(⽤于编码解码HTTP请求);- 然后是开发者使⽤
addNetworkInterceptor(Interceptor)所设置的,它们的⾏为逻辑和使⽤addInterceptor(Interceptor)创建的⼀样,但由于位置不同,所以这⾥创建的Interceptor会看到每个请求和响应的数据(包括重定向以及重试的⼀些中间请求和响应),并且看到的是完整原始数据,⽽不是没有加Content-Length的请求数据,或者Body还没有被gzip解压的响应数据。多数情况,这个⽅法不需要被使⽤; CallServerInterceptor:它负责实质的请求与响应的I/O操作,即往Socket⾥写⼊请求数据,和从Socket⾥读取响应数据。
- ⾸先是开发者使⽤
作业
阅读 OkHttp 源码,理解 OkHttp 原理,并尝试在不借助讲义的情况下讲出 OkHttpClient 中每个重要的成员变量的⽤途,以及每个 Interceptor 的实际作⽤。(不检查)
WebSocket是HTTP的扩展,一般用于金融交易(股票等)
HTTP是C/S
HTTP是无连接的,连接说的是TCP和SSL(TLS)连接