简介
okhttp和HttpURLConnection都是用于网络请求,但okhttp并不是在HttpURLConnection基础上进行封装的,okhttp利用socket编写的一套网络请求库。在功能上更加强大,在性能上也更加优越。同时使用也更加方便。
数据请求
- GET
参数直接拼接到url上,url长度有128字节限制,所以参数过多或者不想直接让别人查看到参数,可以使用POST。
String getRequst(String url) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
- POST
public static Response postRequst(String url, String json) throws IOException {
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response;
}
配置组装
-
OkHttpClient
几乎所以okhttp配置的聚合类,使用构建者模式(OkHttpClient.Builder)组装网络请求需要的配置。具体有那些,以及用法,会在源码分析过程中讲解。
- http(https)请求
newCall(Request request) - WebSocket请求
newWebSocket(Request request, WebSocketListener listener)。
- http(https)请求
-
Request
- HttpUrl url
URL结构:scheme://host:port/path?query#fragmentscheme:通信协议,常用的有http、https、ftp、mailto等。 host:主机域名或IP地址。 port:端口号,可选。省略时使用协议的默认端口,如http默认端口为80。 path:路径由零或多个"/"符号隔开的字符串组成,一般用来表示主机上的一个目录或文件地址。 query:查询,可选。用于传递参数,可有多个参数,用"&"符号隔开,每个参数的名和值用"="符号隔开。 fragment:信息片断字符串,也称为锚点。用于指定网络资源中的片断。
- String method
网络请求类型:POST,GET,HEAD,DELETE,PUT,PATCH,常用的也就前两种。 - Headers headers
网络请求头参数,用一个String数字保存,所以添加的时候应该是一个完整的“key:value”字符串的参数。 - @Nullable RequestBody body
POST请求时,请求参数体。在发起网络请求的时候,利用sink将参数写到流里面。 - Map<Class<?>, Object> tags
从源码看,就是保存实例的集合。
- HttpUrl url
创建任务
- RealCall
持有Transmitter,Request实例。调用execute(同步)和enqueue(异步)方法,请求开始执行。
transmitter.callStart()任务开始执行通知,client.dispatcher().executed(this)将回调加入队列。@Override public Response execute() throws IOException { ... transmitter.timeoutEnter(); transmitter.callStart(); try { client.dispatcher().executed(this); return getResponseWithInterceptorChain(); } finally { client.dispatcher().finished(this); } }
- Transmitter
任务事件发射器,注册EventListener事件接收器,接受任务开始,释放等事件。持有OkHttpClient,Request等实例。 - Dispatcher
任务调度器,持有RealCall等对象。里面有readyAsyncCalls(将要运行的回调),runningAsyncCalls(正在运行的异步回调),runningSyncCalls(正在运行的同步回调)三个双端队列。
执行任务
okhttp使用拦截器链式调用完成网络请求,不同的拦截器完成不同的功能,同时我们可以自定义自己的拦截器,完成特定的功能。
OkHttpClient.Builder提供了两个方法添加自定义拦截器。至于区别,在后面使用到的时候讲解。
- addInterceptor
保存在interceptors对象集合里 - addNetworkInterceptor
保存在networkInterceptors对象集合里
拦截器
开始执行任务
Response response = chain.proceed(originalRequest);
getResponseWithInterceptorChain方法中创建很多任务拦截器,通过链式调用,直到所有拦截器执行完成。首先看一下这个方法里面拦截器添加顺序。
interceptors自定义拦截器 -> RetryAndFollowUpInterceptor -> BridgeInterceptor -> CacheInterceptor -> ConnectInterceptor -> networkInterceptors -> CallServerInterceptor。那么执行的顺序也相同。
RealInterceptorChain,持有所以的拦截器数组,原始的Request,Transmitter等,在proceed方法中调用拦截器中的intercept方法,并创建一个新RealInterceptorChain对象传递给拦截器。
- RetryAndFollowUpInterceptor
网络请求重试拦截器。 - BridgeInterceptor
配置cookie信息,以及一些头信息配置。 - CacheInterceptor
缓存拦截器。 - ConnectInterceptor
网络链接拦截器,这个是整个框架的核心。 - CallServerInterceptor
最后一个拦截器,大概作用就是网络请求最后,通知一些信息给服务器。
返回结果
等所有拦截器执行完成,请求结果从最后一个拦截器依次返回。
网友评论