OkHttp
高效网络框架 is a http client from Square
0、公司 : Square
1、http/2 supports allows all request to the same host to share a socket.
2、connection pooling
3、gzip
4、Response caching for repeat requests
5、using OkHttp is easy
支持 spdy、http2.0、websocket 等协议
支持同步、异步请求
封装了线程池,封装了数据转换,提高性能。
Builder模式
拦截器 - 责任链模式
-
OkHttp的拦截器就是基于责任链模式,每个节点有自己的职责,同时可以选择是否把任务传递给下一个环节
整个过程像工厂流水线一样,传递用户发起的请求 Request,每一个拦截器完成相应的功能,从失败重试和重定向实现、请求头的修改和Cookie 的处理,缓存的处理,建立 TCP 和 SSH 连接,发送 Request 和读取 Response,每一个环节由专门的 Interceptor 负责。
- 自定义 > 自带
- 推进 chain.proceed(chain.request())
class LoggingInterceptor implements Interceptor {
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
// 主要方法 Intercept。会传递一个 Chain 对象过来,可以在 Chain 在执行 proceed 的前后添加代码
Response response = chain.proceed(request);
long t2 = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
return response;
}
}
双任务队列
手动推进队列循环,而不是while循环 节省了资源
Dispather ayncCall
- AsyncCall - Runnable
- 1、enqueue(ayncCall) - readyAsyncCalls
- 2、dispatcher promoteAndExcute()
- 3、iterator readyAsyncCalls
- 4、condition ?
- 5、add to RunningAsyncCalls & asyncCall.excuteOn(excutorService)
- 6、finished : client.dispather().finished(this = asyncCall)
- 7、Recursive call to step 2 (dispatcher promoteAndExcute) -- 手动推进队列循环
应该是单例的OkHttpClient
所有的 HTTP 在进行请求的时候都要使用这一个 Client 。因为每个 OkHttpClient 都对应了自己的连接池和线程池。减少使用连接池和线程池可以减少延迟和内存的使用。相反的如果每个请求都创建一个 OkHttpClient 的话会很浪费内存资源。
OkHttpClient 有三个创建方法
-
第一个方法:直接使用
new OkHttpClient()
来创建一个实例对象就可以了,这个实例对象有默认的配置。默认请求连接超时时间 10 s ,读写超时时间 10 s,连接不成功会自动再次连接。 -
第二个方法:就是通过 Builder的方式来自己定义一个 OkHttpclient 。当然如果你直接 build 没有自己配置参数的话,效果和第一个方法是一样的。
public final OkHttpClient = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor())
.cache(new Cache(cacheDir,cacheSize))
.等等配置
.build();
- 第三个方法:就是通过已有的 OkHttpClient 对象来复制一份共享线程池和其他资源的 OkHttpClient 对象。
OkHttpClient agerClient = client.newBuilder()
.readTimeout(500,TimeUnit.MILLSECONS)
.build();
这种方法的好处就是,当我们有一个特殊的请求,有的配置有点不一样,比如要求连接超过 1 s 就算超时,这个时候我们就可以使用这个方法来生成一个新的实例对象,不过他们共用很多其他的资源,不会对资源造成浪费。
关于 OkHttpClient 的配置改变都在 Builder 中进行
Retrofit
对OkHttp进行了封装
- 可restful风格
- 注解风格(包括httpMethod,msgType),大大简化网络请求代码
@GET,POST ..
@FormUrlEncoded
@Mutilpart
@FieldMap
@Query
@Body
-
apiService动态代理
-
RxJava ,观察者模式
-
最佳实践:网络模块封装
Retrofit + Hilt + RxJava