系列文章
OkHttp学习(一) OSI七层模型和TCP四层模型
OkHttp学习(二) 3.10.0版本的简单使用及其流程梳理
OkHttp学习(三) 3.10.0版本源码阅读之线程池
OkHttp学习(四) 3.10.0版本源码阅读之构建者设计模式
OkHttp学习(五) 3.10.0版本源码阅读之责任链设计模式
OkHttp学习(六) 3.10.0版本源码中的拦截器
OkHttp学习(七) 手写OkHttp之框架搭建
OkHttp学习(八) 手写OkHttp之网络请求实现
OkHttp学习(九) OkHttp的连接池手写实现
OkHttpClient2
public class OkHttpClient2 {
Dispatcher2 dispatcher;
boolean isCanceled;
public boolean getCanceled() {
return isCanceled;
}
public OkHttpClient2() {
this(new Builder());
}
public OkHttpClient2(Builder builder) {
dispatcher = builder.dispatcher;
isCanceled = builder.isCanceled;
}
public final static class Builder {
Dispatcher2 dispatcher;
boolean isCanceled;
public Builder() {
dispatcher = new Dispatcher2();
}
public Builder dispatcher(Dispatcher2 dispatcher) {
this.dispatcher = dispatcher;
return this;
}
// 用户取消请求
public Builder canceled() {
isCanceled = true;
return this;
}
public OkHttpClient2 build() {
return new OkHttpClient2(this);
}
}
public Call2 newCall(Request2 request2) {
// RealCall
return new RealCall2(this, request2);
}
public Dispatcher2 dispatcher() {
return dispatcher;
}
}
Request2
public class Request2 {
public static final String GET = "GET";
public static final String POST = "POST";
private String url;
private String requestMethod = GET; // 默认请求下是GET
private Map<String, String> mHeaderList = new HashMap<>();
public String getUrl() {
return url;
}
public String getRequestMethod() {
return requestMethod;
}
public Map<String, String> getmHeaderList() {
return mHeaderList;
}
public Request2() {
this(new Builder());
}
public Request2(Builder builder) {
this.url = builder.url;
}
public final static class Builder {
private String url;
private String requestMethod = GET; // 默认请求下是GET
private Map<String, String> mHeaderList = new HashMap<>();
public Builder url(String url) {
this.url = url;
return this;
}
public Builder get() {
requestMethod = GET;
return this;
}
public Builder post() {
requestMethod = POST;
return this;
}
/**
* Connection: keep-alive
* Host: restapi.amap.com
* @return
*/
public Builder addRequestHeader(String key, String value) {
mHeaderList.put(key, value);
return this;
}
public Request2 build() {
return new Request2(this);
}
}
}
Call2
public interface Call2 {
void enqueue(Callback2 responseCallback);
}
RealCall2
public class RealCall2 implements Call2 {
private OkHttpClient2 okHttpClient2;
private Request2 request2;
public RealCall2(OkHttpClient2 okHttpClient2, Request2 request2) {
this.okHttpClient2 = okHttpClient2;
this.request2 = request2;
}
private boolean executed;
@Override
public void enqueue(Callback2 responseCallback) {
// 不能被重复的执行 enqueue
synchronized (this) {
if (executed) {
executed = true;
throw new IllegalStateException("不能被重复的执行 enqueue Already Executed");
}
}
okHttpClient2.dispatcher().enqueue(new AsyncCall2(responseCallback));
}
final class AsyncCall2 implements Runnable {
public Request2 getRequest() {
return RealCall2.this.request2;
}
private Callback2 callback2;
public AsyncCall2(Callback2 callback2) {
this.callback2 = callback2;
}
@Override
public void run() {
// 执行耗时操作
boolean signalledCallback = false;
try {
Response2 response = getResponseWithInterceptorChain();
// 如果用户取消了请求,回调给用户,说失败了
if (okHttpClient2.getCanceled()) {
signalledCallback = true;
callback2.onFailure(RealCall2.this, new IOException("用户取消了 Canceled"));
} else {
signalledCallback = true;
callback2.onResponse(RealCall2.this, response);
}
}catch (IOException e) {
// 责任的划分
if (signalledCallback) { // 如果等于true,回调给用户了,是用户操作的时候 报错
System.out.println("用户再使用过程中 出错了...");
} else {
callback2.onFailure(RealCall2.this, new IOException("OKHTTP getResponseWithInterceptorChain 错误... e:" + e.toString()));
}
} finally {
// 回收处理
okHttpClient2.dispatcher().finished(this);
}
}
private Response2 getResponseWithInterceptorChain() throws IOException {
Response2 response2 = new Response2();
response2.setBody("流程走通....");
return response2;
}
}
}
Dispatcher2
public class Dispatcher2 {
private int maxRequests = 64; // 同时访问任务,最大限制64个
private int maxRequestsPerHost = 5; // 同时访问同一个服务器域名,最大限制5个
private Deque<RealCall2.AsyncCall2> runningAsyncCalls = new ArrayDeque<>(); // 存储运行的队列
private Deque<RealCall2.AsyncCall2> readyAsyncCalls = new ArrayDeque<>(); // 存储等待的队列
public void enqueue(RealCall2.AsyncCall2 call) {
// 同时运行的队列数 必须小于 配置的64 && 同时访问同一个服务器域名 不能超过5个
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call); // 先把任务加入到 运行队列中
executorService().execute(call); // 然后再执行....
} else {
readyAsyncCalls.add(call); // 加入到等待队列中
}
}
/**
* 缓存方案
* @return
*/
public ExecutorService executorService() {
ExecutorService executorService =
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName("自定义的线程....");
thread.setDaemon(false); // 不是守护线程
return thread;
}
});
return executorService;
}
/**
* 判断AsyncCall2中的Host,在运行的队列中,计数,然后放回
*
* 参数AsyncCall2.Request.Host == runningAsyncCalls.for{AsyncCall2.Request.Host} +1
*
* @param call
* @return
*/
private int runningCallsForHost(RealCall2.AsyncCall2 call) {
int count = 0;
if (runningAsyncCalls.isEmpty()) {
return 0;
}
SocketRequestServer srs = new SocketRequestServer();
/**
* 遍历运行队列里面的所有任务,取出任务host == call.host +1
*/
for (RealCall2.AsyncCall2 runningAsyncCall : runningAsyncCalls) {
// 取出任务host == call.host
if (srs.getHost(runningAsyncCall.getRequest()).equals(call.getRequest())) {
count ++;
}
}
return count;
}
/**
* 1.移除运行完成的任务
* 2.把等待队列里面所有的任务取出来【执行】 AsyncCall2.run finished
* @param call2
*/
public void finished(RealCall2.AsyncCall2 call2) {
// 当前运行的任务 给回收
runningAsyncCalls.remove(call2);
// 考虑等待队列里面是否有任务,如果有任务是需要执行的
if (readyAsyncCalls.isEmpty()) {
return;
}
// 把等待队列中的任务给 移动 运行队列
for (RealCall2.AsyncCall2 readyAsyncCall : readyAsyncCalls) {
readyAsyncCalls.remove(readyAsyncCall); // 删除等待队列的任务
runningAsyncCalls.add(readyAsyncCall); // 把刚刚删除的等待队列任务 加入到 运行队列
// 开始执行任务
executorService().execute(readyAsyncCall);
}
}
}
Callback2
public interface Callback2 {
void onFailure(Call2 call, IOException e);
void onResponse(Call2 call, Response2 response) throws IOException;
}
Response2
public class Response2 {
private String body;
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String string() {
return body;
}
}
SocketRequestServer
public class SocketRequestServer {
/**
* 通过Request对象,寻找到域名HOST
* @param request2
* @return
*/
public String getHost(Request2 request2) {
return null;
}
}
测试代码
/**
* 使用我们自己的OKHTTP
* @param view
*/
public void useMyOkhttp(View view) {
OkHttpClient2 okHttpClient2 = new OkHttpClient2.Builder().build();
Request2 request2 = new Request2.Builder().url(PATH).build();
Call2 call2 = okHttpClient2.newCall(request2);
// 执行异步
call2.enqueue(new Callback2() {
@Override
public void onFailure(Call2 call, IOException e) {
System.out.println("自定义OKHTTP请求失败....");
}
@Override
public void onResponse(Call2 call, Response2 response) throws IOException {
System.out.println("OKHTTP请求成功.... result:" + response.string());
}
});
}