Android network request framework okhttp

OkHttp

OKhttp, an android network framework, is an open source project for processing network requests. It is the most popular lightweight framework on the Android side.

use

1. Get method

new OkHttpClient -> Construct Request object -> newCall ->enqueue or execute

//同步
String url = "http://wwww.baidu.com" 
OkHttpClient okHttpClient = new OkHttpClient()
final Request request = new Request.Builder()
.url(url)
.get()
.build();
Response response= okHttpClient.newCall(request).execute()
String result= response.body().toString

//异步
String url = "http://wwww.baidu.com" 
OkHttpClient okHttpClient = new OkHttpClient()
final Request request = new Request.Builder()
.url(url)
.get()
.build()
okHttpClient.newCall(request).enqueue(ne Callback(){
    
    
@Override
public void onFailure(Call call, IOException e) {
    
    
Log.d(TAG, "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
    
    
Log.d(TAG, "onResponse: " + response.body().string());
}
})

2. Post method

new OkHttpClient -> Construct RequestBody, specify mimeType -> Construct request

OkHttpClient okHttpClient= new OkHttpClient()
RequestBody requestBody=new FormBody.Builder()
.add("username","danding")
.build()
Request request= new RequestBody.Builder()
.url(url)
.post(requestBody)
.build()
okHttpClient.newCall(request).enqueue(new CallBack(){
    
    
@Override
public void onFailure(Call call, IOException e) {
    
    
Log.d(TAG, "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException
{
    
    
Log.d(TAG, "onResponse: " + response.body().string());
}
})

3. Custom Interceptor

@Override
public Response intercept(Chain chain) throws IOException {
    
    
Request request=chain.request()
//todo....
Response response=chain.proceed(request)
return response
}

source code

1. Create OkHttpClient

public OkHttpClient() {
    
     //直接创建的 OkHttpClient对象并且默认构造builder对象进
行初始化
this(new Builder());
}
OkHttpClient(Builder builder) {
    
    
this.interceptors = Util.immutableList(builder.interceptors)
...
}

2. Create a Request

Code new Request.Builder().url(url).build()

public final class Request {
    
    
public Builder() {
    
    
this.method = "GET";
this.headers = new Headers.Builder();
}
public Builder url(String url) {
    
    
HttpUrl parsed = HttpUrl.parse(url); //获取scheme、host、port等信息
return url(parsed) //设置this.url成员
}
}

3.okHttpClient.newCall(request)

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory
{
    
    
@Override
public Call newCall(Request request) {
    
    
return new RealCall(this, request, false /* for web socket */);
}
}
final class RealCall implements Call {
    
    
@Override
public void enqueue(Callback responseCallback) {
    
    
synchronized (this) {
    
    
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback))
}
}
class AsyncCall extends NamedRunnable{
    
     //implements Runnable
protected void execute() {
    
    
try {
    
    
Response response = getResponseWithInterceptorChain()//!!!核心
... List<Interceptor> interceptors = new ArrayList<>()
interceptors.addAll(client.interceptors())
interceptors.add(retryAndFollowUpInterceptor)
interceptors.add(new BridgeInterceptor(client.cookieJar()))
interceptors.add(new ConnectInterceptor(client))
interceptors.add(new CallServerInterceptor(forWebSocket))
... Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest)
... public Response proceed(Request request, StreamAllocation
streamAllocation, HttpCodec httpCodec ,RealConnection connection)
throws IOException {
    
    
if (index >= interceptors.size()) throw new AssertionError()
val interceptor=interceptos.get(index)
Response response = interceptor.intercept(next)
}
responseCallback.onResponse(RealCall.this, response)
}
}

4. Dispatcher thread pool

/** 最大并发请求数为64 */
private int maxRequests = 64;
/** 每个主机最大请求数为5 */
private int maxRequestsPerHost = 5;
/** 线程池 */
private ExecutorService executorService;
/** 准备执行的请求 */
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
/** 正在执行的异步请求,包含已经取消但未执行完的请求 */

private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
/** 正在执行的同步请求,包含已经取消单未执行完的请求 */
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
> enqueue //压入请求
synchronized void enqueue(AsyncCall call) {
    
    
//maxRequest==64
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) <
maxRequestsPerHost) {
    
    
runningAsyncCalls.add(call); //压入正在执行队列
executorService().execute(call);
} else {
    
    
readyAsyncCalls.add(call); //压入就绪队列
}
}

5.Interceptor

>BridgeInterceptor -> 添加Content-TypeContent-LengthUser-Agent等协议头
>ConnectInterceptor -> ....
>CallServerInterceptor -> 实际发送网络请求

Guess you like

Origin blog.csdn.net/weixin_44008788/article/details/129001796