6.1开源框架-okhttp网络框架-详解

okhttp网络框架

    1. OkHttp使用简介
    1. OkHttp源码剖析

1.OkHttp使用简介




    1. 创建客户端
      OkhttpClient client = new OkHttpClient();//作为单例,这样所有的请求可以公共response缓存和线程池
    1. 创建Request对象
      Request request = new Request.Builder().url("http://xxx").build();
      图上:封装了Http的一些请求信息
      Builder模式构建,builder模式会将它的显示和创建所分离
    1. 创建Call对象,call对象就是一个Http请求,execute开始执行
      okttp3.Response response = client.newCall(request).execute();
      //其中Call是连接request和Response的的桥梁
      Call对象既可以同步获取时间,也可以异步获取获取
     //同步获取方法   
    if(!response.isSuccessful())
        throw new IOException("Unexpected code "+response);
        
    Headers responseHeaders = response.headers()
    for(int i=0;i

同步获取数据它会阻塞当前线程去请求数据,返回response对象给线程.response也会包含状态码,响应头,响应body

    //异步获取方法:
    //前两步一样:
    client.newCall(request).enqueue(new Callback(){
        public void onFailure(Call call,IOException e){
            e.printStackTrace();
        }
        public void onResponse(Call call,okhttp3.Response response) throws IOExcepiton{
            if(!response.isSuccessful())
                throw new IOException("Unexpected code "+response);
            Headers responseHeaders = response.headers();
            for(int i=0;i

enqueue方法不会阻塞当前进程,会开启子线程,网络请求在子线程操作,当请求结束后,会回调成功、失败(在工作线程中执行)

2.OkHttp源码剖析

图:



7-1 okhttp网络框架面[00_06_58][20180721-155323-5].jpg
1. Application
2.Application INTERCEPTORS 包括↓request ↑response
OkHttp core

1.↓CACHE ↑CACHE 2.NETWORK INTERCEPTORS ↓request ↑response

    1. 创建客户端
      OkhttpClient client = new OkHttpClient();
  • 2.创建Request对象
    Request request = new Request.Builder().url("http://xxx").build();
    //builder模式的作用就是将一个复杂对象的构建与他的表示像分离,这样就可以是同样的构建过程创建不同的的表示
  • 3.okttp3.Response response = client.newCall(request).execute();
    • newCall()里面是 return new RealCall(this.request,false);
        RealCall类中方法;
        public Response execute()throw IOException {
            synchronized(this){
            //检查
            if(executed) throw new IllegalStateException("Already Executed")
            executed = true;
            }
            //每个call只能执行一次,如果想要一个完全的方法,可以使用call.clone方法
            captureCallStackTrace();
            try{
                client.dispatcher().executed(this);//开始同步请求
                //dispatcher官方文档中它是一个异步请求的策略,但是它也能做一些同步请求的操作
                Response result = getResponseWithInterceptorChain();
                //okhttp最精髓的地方,拦截器。经过拦截器拦截后,会返回一个response结果给我们的http
                if(result = null) throw new IOException("Canceled");
                return result;
            }finally{
                client.dispathcher().finished(this);
                //通知我们的dispatcher 任务完成
            }
        }
        //以下finished的源码
            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();
                }
            }

//做的工作:把请求队列关闭
在同步操作中,client.dispatcher().executed(this)中涉及到dispatcher并不是真正的去做异步操作,只是告诉我们执行的状态。开始执行时executed,执行完了finished方法

真正做网络请求并返回结果的是方法getResponseWithInterceptorChain();

        Response getResponseWithInterceptorChain() throw IOExption{
            List interceptors = new ArrayList<>();
            interceptors.addAll(client.interceptors);
            interceptors.add(retryAndrFollowUpInterceptor);
            interceptors.add(new BirdgeInterceptor(client.cookieJar()));
            interceptors.add(new CacheInterceptor(client.internalCache()));
            interceptors.add(new ConnectInterceptor(client));
            
            if(!forWebSocket){
                interceptors.addAll(client.networkInterceptors());
            }
            interceptors.add(new CallServerInterceptor(forWebSocket));
            Intercepor.Chain chain = new RealInterceptorChain(interceptors,null,null,null,0,originalRequest);
            return chain.proceed(originalRequest);
        }

interceptor 它把网络请求缓存,压缩等所有功能都统一起来,每一个都是interceptor,连接起来成了一个interceptor.chain

  • 各拦截器
    retryAndrFollowUpInterceptor -->失败重试,重定向,重定向另外一个url
    BirdgeInterceptor 为了把用户构造的请求转换成发送到服务器的请求,然后把服务器的响应转回给用户,进行一些友好输出的响应,这是一个桥接的interceptor
    CacheInterceptor :缓存拦截器,读取,更新缓存
    ConnectInterceptor :和服务端进行连接的拦截器
    CallServerInterceptor :网络的服务器端的连接
        具体分析一个拦截器:
            CallServerInterceptor
            类结构
            +boolean forWebSocket:构造赋值
            --------------------
            public Response intercept(Chain chain) throws IOExcetion{
                
            }
  • 主要作用,向服务器发送一个头部,如果有body也会发送。发送之后获取response的头部和body
  • 其中httpCodec.writeRequestHeaders(request),需要关注httpCodec它的内部是Okio对象 ,okio封装了socket;
  • interceptor设计是一个分层的思想,每一个interceptor就是一层,这是tcp/ip协议是异曲同工之秒、
  • 每一层简化了,每一层只关心每一层的事情,比如CallServerInterceptor只关心和服务器的连接;
    把各种复杂的任务拆分成一个一个独立的任务,这样对以后的拓展很有帮助。

异步请求源码分析

        enqueue也是在RealCall里面处理的
        public void enqueue(Callback responseCallback){
            //同上检查是否已执行
            captureCallStackTrace();
            client.dispatcher().enqueue(new AsyncCall(responseCallback));
        }
        
        Dispatcher 的enqueue方法:
        synchronized void enqueue(AsyncCall call){
            if(runningAsyncCalls.size()

类中有是三个集合

        Dequeue readyAsyncCalls = new ArrayQeueue<>();//正在准备的异步请求
        Dequeue runningAsyncCalls = new ArrayQeueue<>();
        //正在运行的异步请求
        Dequeue runningSyncCalls  = new ArrayQeueue<>();//
        //正在运行的同步请求
        executorService() 返回一个线程池(java当中的一个并发类)
            if(executorService == null){
                executorService = new ThreadPoolExecutor(0,Integer.MAIN_VALUE,60,TimeUnit.SECONDS,NEW SynchronourQueue(),Util.threadFactory("OkHttp Dispatcher",false));
            }
            return executorService;

总结

你可能感兴趣的:(6.1开源框架-okhttp网络框架-详解)