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

2018-11-18  本文已影响0人  205蚁

okhttp网络框架

1.OkHttp使用简介




     //同步获取方法   
    if(!response.isSuccessful())
        throw new IOException("Unexpected code "+response);
        
    Headers responseHeaders = response.headers()
    for(int i=0;i<responseHeaders.size();i++){
        System.out.println(responseHeaders.name(i)+": "+responseHeaders.value(i));
    }
    System.out.println(response.body().string());

同步获取数据它会阻塞当前线程去请求数据,返回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<responseHeaders.size();i++){
                System.out.println(responseHeaders.name(i)+": "+responseHeaders.value(i));
            }
            System.out.println(response.body().string());
        }
    })

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

        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 <T> void finished(Deque<T> 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<Interceptor> 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

        具体分析一个拦截器:
            CallServerInterceptor
            类结构
            +boolean forWebSocket:构造赋值
            --------------------
            public Response intercept(Chain chain) throws IOExcetion{
                
            }

异步请求源码分析

        enqueue也是在RealCall里面处理的
        public void enqueue(Callback responseCallback){
            //同上检查是否已执行
            captureCallStackTrace();
            client.dispatcher().enqueue(new AsyncCall(responseCallback));
        }
        
        Dispatcher 的enqueue方法:
        synchronized void enqueue(AsyncCall call){
            if(runningAsyncCalls.size()<maxREquests && runningCallsForHost(call) < maxRequestsPerHost){
                runningAsyncCalls.add(call);//满足要求添加到队列里面
                executorService().execute(call);
            }else{
                readyAsyncCalls.add(call);
            }
        }
        

类中有是三个集合

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

总结

上一篇下一篇

猜你喜欢

热点阅读