网络底层框架:OkHttp 实现原理

OkHttp3简单使用教程(一):请求和响应
https://www.jianshu.com/p/f3f228d3598c

\n
HTTP请求报文主要由请求行、请求头部、请求正文3部分组成.

请求行:由请求方法,URL,协议版本三部分构成,之间用空格隔开
请求 Content-Language

请求zhengwen

/n


23    URL带的参数


HTTP响应报文格式:
HTTP响应报文主要由状态行、响应头部、响应正文3部分组成


HTTP响应报文主要由状态行、响应头部、响应正文3部分组成

Content-Charset

由3部分组成,分别为:协议版本,状态码,状态码描述,之间由空格分隔


OkHttpClient Request .url.build
newCall

.enquene
onResponse


HttpUrl.Builder  newBuilder

params.keySet
setQueryParameter key,params.get key


.url .headers      .get .build

 //同步
Response response = call.execute()
if(response.isSuccessful()){
     //响应成功
}

.post urlBuilder.build

httpClient.newCall request

Call call

//URL带的参数
HashMap<String,String> params = new HashMap<>();
//GET 请求带的Header
HashMap<String,String> headers= new HashMap<>();

       Request request = new Request.Builder()
                .url(urlBuilder.build())
                .headers(headers == null ? new Headers.Builder().build() : Headers.of(headers))

// 构造Request->call->执行
 Request request = new Request.Builder()
                            .headers(extraHeaders == null ? new Headers.Builder().build() : Headers.of(extraHeaders))//extraHeaders 是用户添加头
                            .url(url)
                            .post(urlBuilder.build())//参数放在body体里

MultipartBody.Builder   RequestBody Request

OkHttp       POST 


sink.write content


RequestBody

HTTP响应报文格式:
HTTP响应报文主要由状态行、响应头部、响应正文3部分组成

HTTP请求报文格式:
HTTP请求报文主要由请求行、请求头部、请求正文3部分组成.

Http请求中Content-Type

Content-Type


MultiPartBody的BufferedSink

MediaType  Part


contentLength


sink
 body
 
 /Part 的定义,Part 是由Headers+RequestBody组成

OKHttp源码解析
https://www.cnblogs.com/zn615/p/8182304.html
part/


OkHttpClient build 

newCall0

getResponseWithInterceptorChain

interceptors

Request url method header body

excute

OkHttpClient 

Dispatcher Protocol ConnectionSpec 

ConnectionPool  

Interceptor 
Interceptor.Chain

InternalCache


resources
看到这,如果你还不明白的话,也没关系,在OkHttp中只是设置用的的各个东西。真正的流程要从里面的newCall()方法中说起:

       /**
        *  Prepares the {@code request} to be executed at some point in the future.
        *  准备将要被执行的request
        */
        @Override
        public Call newCall(Request request) {
            return new RealCall(this, request);
        }


client.newCall(re)


Response response = client.newCall(request).execute();这就代码就开启了整个GET请求的流程:

client.dispatcher.execute this

client.dispatcher.finished

getResponseWithInterceptorChain

用 getResponseWithInterceptorChain() 函数获取 HTTP 返回结果,从函数名可以看出,这一步还会进行一系列“拦截”操作。


//拦截器的责任链。


RealInterceptorChain next = RealInterceptorChain
interceptors

Response response = 
interceptor.intercept(next);


Request.Builder

responseBuilder.build


ConnectInterceptor;


realChain.request
realChain.streamAllocation

realChain.proceed request,streamAllocation,httpCodec,connection


NetworkInterceptors
CallServerInterceptor  httpStream .streamAllocation
chain.request


HttpCodec.request


OkHttpClient request 
client.newCall request .enqueue
onResponse

resource.headers非必须

client.dispatcher.enquene     AsyncCall 


Dispatcher enquene Call

client.dispatcher.finished this

Response response = getResponseWithInterceptorChain();

OkHttpClient Builder
build
OkHttpClient
newCall
RealCall    
execute enquene
Dispatcher 
intercepters

originalRequest getResponseWithInterceptorChain

CacheInterceptor

ConnectInterceptor
networkInterceptors


CallServerInterceptor

Request url method header body


Response  code message headers非必须 body

在配置 OkHttpClient 时设置的 interceptors;
负责失败重试以及重定向的 RetryAndFollowUpInterceptor;
负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的 BridgeInterceptor;
负责读取缓存直接返回、更新缓存的 CacheInterceptor;
负责和服务器建立连接的 ConnectInterceptor;
配置 OkHttpClient 时设置的 networkInterceptors;
负责向服务器发送请求数据、从服务器读取响应数据的 CallServerInterceptor。
在return chain.proceed(originalRequest);中开启链式调用:

chain.proceed originalRequest 

//3,新建一个call对象
Call call = mOkHttpClient.newCall(request); 
//4,请求加入调度,这里是异步Get请求回调
call.enqueue(new Callback()


newCall enquene

Request .url 

call.excute call.enquene call.cancel


 MultipartBody.Builder urlBuilder = new MultipartBody.Builder()
                            .setType(MultipartBody.FORM);

MultiPartBody.Builder   MultiPartBody.FORM

addFormDataPart

 .post(urlBuilder.build())//参数放在body体里
 
   urlBuilder.setQueryParameter(key, params.get(key));
   setQueryParameter
  .url(urlBuilder.build())


RequestBody = contentType + BufferedSink + RequestBody

  /** Writes the content of this request to {@code sink}. */
  //写入缓存sink
  public abstract void writeTo(BufferedSink sink) throws IOException;

writeTo BufferedSink sink


charset contentType  MediaType


new RequestBody 
//文件写入BufferedSink 
          source = Okio.source(file);
          sink.writeAll(source);

          sink.writeAll

Http请求中Content-Type

MediaType FORM multipart/form-data

、  Part part = parts.get(p);
     //Part的Headers和RequestBody 
      Headers headers = part.headers;
      RequestBody body = part.body;
      
      
      
      part.headers非必须
      part.body
      
           return new Part(headers, body);
           
           
    createFormData       
        Part.create body
    Headers headers RequestBody body
    
    重点:RequestBody create(MediaType contentType, final File file)构造文件请求体RequestBody ,并且添加到MultiPartBody中
    
    
    multipart/form-data
      MultipartBody.Builder urlBuilder= 
      new MultipartBody.Builder().
      setType(MultipartBody.FORM);
      
      files.keySet
      
     RequestBody.create(MediaType.parse("multipart/form-data"), files.get(key))
    
    addFormDataPart 
    url post newCall0 request.enquene
        

onResponse

MultiPartBody Headers body
RequestBody


SparseArray<FileBlock>

对文件块分块多线程异步上传
url domain/sync/img/upload
method POST 

data = {
}

ExcutorService threadPool = ExcutorService.newCachedThreadPool


       while ((len = in.read(buf)) >= 0 && nowSeek < seekEndWrite) {
                                sink.write(buf, 0, len);
                                
        sink.write buf,0,len                        
                                
                     //组装其它参数
                    MultipartBody.Builder urlBuilder = new MultipartBody.Builder()
                            .setType(MultipartBody.FORM);                

    MultiPartBody.Builder                          
                            
                 //把文件块的请求体添加到MultiPartBody中
                    urlBuilder.addFormDataPart(fileKey, file.getName(), requestBody);                
                            url post build
    
        httpClient.newCall request
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值