android网络请求流程图,Android OKHttp系列1-流程总结

1、 调用示例

同步方式:

new Thread(new Runnable() {

@Override

public void run() {

try {

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder().url("http://www.baidu.com").build();

Response response = client.newCall(request).execute();

Log.d(TAG, "response sync:" + response.toString());

} catch (Exception e) {

e.printStackTrace();

}

}

}).start();

通过追溯源码,流程图如下:

d4df9962b203

image

异步方式:

try {

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder().url("http://www.baidu.com").build();

client.newCall(request).enqueue(new Callback() {

@Override

public void onFailure(Request request, IOException e) {

}

@Override

public void onResponse(Response response) throws IOException {

Log.d(TAG, "response async:" + response.toString());

}

});

} catch (Exception e) {

e.printStackTrace();

}

通过追溯源码,流程图如下:

d4df9962b203

image

分析

同步和异步请求的核心方法都是getResponseWithInterceptorChain(),需要注意的是,同步方法没有在工作线程干活,而异步方法是在线程池里面执行,Android不允许在主线程里面做网络请求操作,如果同步请求的话,还必须在非主线程中。

异步方式请求是执行enqueue方法,有两个列表维护执行状态,runningAsyncCalls和readyAsyncCalls,分别是正在执行和等待执行列表,而同步方式则是直接提交请求。异步请求当一次AsyncCall执行完毕之后,在Dispatcher的promoteCalls方法会做两个状态列表的切换,等待列表切换到正在执行列表,同时删除等待列表中最前面的Call。如下:

private void promoteCalls() {

if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.

if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.

for (Iterator i = readyAsyncCalls.iterator(); i.hasNext(); ) {

AsyncCall call = i.next();

if (runningCallsForHost(call) < maxRequestsPerHost) {

i.remove();

runningAsyncCalls.add(call);

executorService().execute(call);

}

if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.

}

}

遍历readyAsyncCalls列表里面的call,如果正在运行并小于最大的请求数,就可以加到runningAsyncCalls中了,然后接下来execute执行这个请求。

而promoteCalls方法是被Dispatcher的finished方法执行。RealCall中同步或异步execute方法执行完毕后会在finally中执行client.dispatcher().finished(this)方法,如下:

void finished(AsyncCall call) {

finished(runningAsyncCalls, call, true);

}

/** Used by {@code Call#execute} to signal completion. */

void finished(RealCall call) {

finished(runningSyncCalls, call, false);

}

private void finished(Deque calls, T call, boolean promoteCalls) {

int runningCallsCount;

Runnable idleCallback;

synchronized (this) {

if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");

if (promoteCalls) promoteCalls();

runningCallsCount = runningCallsCount();

idleCallback = this.idleCallback;

}

if (runningCallsCount == 0 && idleCallback != null) {

idleCallback.run();

}

}

第一个是finished异步请求完成之后调用,第二finished是同步请求完成之后调用,最终都会调用到带泛型参数的finished,并将执行完的call从runningAsyncCalls(异步)或runningSyncCalls(同步)中删除。promoteCalls参数用来区分是否是异步请求,如果是的话,执行promoteCalls方法。

文章将同步至微信公众号:Android部落格

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值