Android Okhttp3的使用与运行流程

基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun okhttp3Demo() {
        val client: OkHttpClient = OkHttpClient.Builder().build()//创建OkHttpClient
        val r: Request = Request.Builder().url("").build()//创建Request请求
        val call:okhttp3.Call = client.newCall(r)//创建一个Call
        //添加回调并且添加到等待缓存
        call.enqueue(object : okhttp3.Callback {
            override fun onFailure(call: okhttp3.Call, e: IOException) {
 
            }
 
            override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
 
            }
        })
        //call.execute()//直接加入运行缓存
    }

 

运行过程图

 

 

 

Call接口的实现类RealCall 

  HttpClient调用newCall(r:Request)方法 创建Call的实现类RealCall

1
2
3
@Override public Call newCall(Request request) {
  return RealCall.newRealCall(this, request, false /* for web socket */);
}

  跳转到RealCall的newRealCall方法

1
2
3
4
5
6
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.eventListener = client.eventListenerFactory().create(call);
    return call;
  }

  找到RealCall的enqueue()方法

1
2
3
4
5
6
7
8
9
10
@Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
        if (executed) throw new IllegalStateException("Already Executed");
        executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    //调用了HttpClient的Dispatcher的enqueue方法  此时创建了一个Runable的实现类 AsyncCall
    client.dispatcher().enqueue(new RealCall.AsyncCall(responseCallback));
}

  先看AsyncCall  实现了NamedRunnable接口  NamedRunnable实现了Runnable  其run方法调用了AsyncCall的execute()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public abstract class NamedRunnable implements Runnable {
  protected final String name;
 
  public NamedRunnable(String format, Object... args) {
    this.name = Util.format(format, args);
  }
 
  @Override public final void run() {
    String oldName = Thread.currentThread().getName();
    Thread.currentThread().setName(name);
    try {
      execute();
    } finally {
      Thread.currentThread().setName(oldName);
    }
  }
 
  protected abstract void execute();
}

  进入AsyncCall方法的execute()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override protected void execute() {
        try{
            //...other
            //添加interceptors拦截器  责任链
            Response response = getResponseWithInterceptorChain();
            //...other
        } finally {
            client.dispatcher().finished(this);
        }
    }
 
    Response getResponseWithInterceptorChain() throws IOException {
        // Build a full stack of interceptors.
        List<Interceptor> interceptors = new ArrayList<>();
        interceptors.addAll(client.interceptors());
        interceptors.add(retryAndFollowUpInterceptor);
        interceptors.add(new BridgeInterceptor(client.cookieJar()));
        interceptors.add(new CacheInterceptor(client.internalCache()));
        interceptors.add(new ConnectInterceptor(client));
        if (!forWebSocket) {
            interceptors.addAll(client.networkInterceptors());
        }
        interceptors.add(new CallServerInterceptor(forWebSocket));
 
        Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
                originalRequest, this, eventListener, client.connectTimeoutMillis(),
                client.readTimeoutMillis(), client.writeTimeoutMillis());
 
        return chain.proceed(originalRequest);
    }

  RealInterceptorChain实现拦截器功能  分别调用拦截器的proceed()方法执行网络请求返回Response

 

Dispatcher

  Call看完接着进入HttpClient的Dispatcher的enqueue方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//准备中的异步队列
    private final Deque<RealCall.AsyncCall> readyAsyncCalls = new ArrayDeque<>();
    //执行中的异步队列
    private final Deque<RealCall.AsyncCall> runningAsyncCalls = new ArrayDeque<>();
    //执行中的同步队列
    private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
     
    void enqueue(RealCall.AsyncCall call) {
        synchronized (this) {
            readyAsyncCalls.add(call);
        }
        //处理和执行线程
        promoteAndExecute();
    }
     
    private boolean promoteAndExecute() {
        assert (!Thread.holdsLock(this));
        List<RealCall.AsyncCall> executableCalls = new ArrayList<>();
        boolean isRunning;
        synchronized (this) {//将线程进行缓存处理
            for (Iterator<RealCall.AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
                //从readyAsyncCalls中取出可执行线程并添加到runningAsyncCalls中 并执行线程
                RealCall.AsyncCall asyncCall = i.next();
                if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
                if (runningCallsForHost(asyncCall) >= maxRequestsPerHost) continue; // Host max capacity.
                i.remove();
                executableCalls.add(asyncCall);
                runningAsyncCalls.add(asyncCall);
            }
            isRunning = runningCallsCount() > 0;
        }
 
        for (int i = 0, size = executableCalls.size(); i < size; i++) {
            RealCall.AsyncCall asyncCall = executableCalls.get(i);
            //调用RealCall的executeOn方法  其内部执行 executorService.execute(this);线程池启动线程
            asyncCall.executeOn(executorService());
        }
 
        return isRunning;
    }

  关于Dispatcher内部的线程池--线程池另外写一个随笔

1
2
3
4
5
6
7
8
public synchronized ExecutorService executorService() {
       if (executorService == null) {
           //创建一个线程池
           executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
                   new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
       }
       return executorService;
   }

  

 

posted @   bg_不够  阅读(383)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示