OkHttp网络库深入解析

作者: wxyass 分类: Android 发布时间: 2018-03-12 20:05

一 Okhttp框架流程

OkHttpClient 单一实例
Request 封装请求报文信息,url,请求头

RealCall
一个实际请求对象

Dispatcher
分发器 根据上一步接收的同步/异步请求进行分发 会将RealCall封装进来

interceptors
拦截器列,主要看5个拦截器

  • RetryandFollow 失败,重新请求
  • Bridge 请求前操作
  • Cache 处理缓存信息
  • Connect 为当前请求,找一个合适的连接
  • CallServer 向服务器发起请求,并接收返回的信息

二 Okhttp集成

1 添加依赖库

//网络依赖
compile 'com.squareup.okio:okio:1.15.0'
compile 'com.squareup.okhttp3:okhttp:3.6.0'

2 添加权限

<!--网络权限-->
<uses-permission android:name="android.permission.INTERNET"/>

三 OkHttp同步请求

1 创建OkHttpClient客户端类
2 创建请求报文信息Request对象
3 将Request封装成Call对象,Call对象可理解为连接Request与Response的桥梁
4 调用call.execute()发送同步请求,获取响应报文信息Response对象
5 打印response.body().string()

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 同步请求    
        getDatasync();
    }

    // 同步请求必须放在子线程中,防止阻塞线程
    public void getDatasync() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                syncRequest();
            }
        }).start();
    }

    // 发起同步请求
    public void syncRequest() {
        // 1 创建OkHttpClient客户端类
        OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(5, TimeUnit.SECONDS)
                .build();

        // 2 创建请求报文信息Request对象
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .get()
                .build();

        // 3 将Request封装成Call对象,Call对象可理解为连接Request与Response的桥梁
        Call call = client.newCall(request);

        try {
            // 4 调用call.execute()发送同步请求,获取响应报文信息Response对象
            Response response = call.execute();

            if (response.isSuccessful()) {
                // 5 打印response.body().string()
                Log.d("wxyass", "res==" + response.body().string());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四 OkHttp异步请求

1 创建OkHttpClient客户端类
2 创建请求报文信息Request对象
3 将Request封装成Call对象,Call对象可理解为连接Request与Response的桥梁
4 调用call.enqueue()发送异步请求,在Callback中获取响应报文信息Response对象
5 打印response.body().string()

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 同步请求
        // getDatasync();
        // 异步请求
        asyRequest();
    }

    // 异步请求  
    private void asyRequest() {
        // 1 创建OkHttpClient客户端类
        OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(5, TimeUnit.SECONDS)
                .build();

        // 2 创建请求报文信息Request对象
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .get()
                .build();

        // 3 将Request封装成Call对象,Call对象可理解为连接Request与Response的桥梁
        Call call = client.newCall(request);

        // 4 调用call.enqueue()发送异步请求,在Callback中获取响应报文信息Response对象
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("Fail");
            }

            @Override
            public void onResponse(Call call, Response response)
                    throws IOException {
                // 5 打印response.body().string()
                System.out.println("asy==" + response.body().string());
            }
        });
    }
}

问题1:okhttp如何实现同步异步请求

发送的同步/异步请求都会在dispatcher中管理其状态

问题2: 到底什么是dispatcher

dispatcher的作用为维护请求的状态,并维护一个线程池,用于执行请求

拦截器

拦截器是okhttp中提供一种强大机制,它可以实现网络监听、请求以及响应重写、请求失败重试等功能

  • RetryandFollowUpInterceptor 重试、重定向拦截器
  • BridgeInterceptor 桥接适配拦截器 (添加一些用户未填写,却必须的请求头信息)
  • CacheInterceptor 缓存拦截器
  • ConnectInterceptor 连接拦截器
  • CallServerInterceptor 数据流拦截器

拦截器总结1

1 创建一些列拦截器,并将其放入一个拦截器list中
2 创建一个拦截器链RealInterceptorChain,并执行拦截器链的proceed方法

拦截器总结2

1 在发起请求前对request进行处理
2 调用下一个拦截器,获取response
3 对response进行处理,返回给上一个拦截器

RetryandFollowUpInterceptor重试拦截器

1 创建StreamAllocation对象
2 调用RealInterceptorChain.proceed(…)进行网络请求
3 根据异常结果或者响应结果判断是否要进行重新请求
4 调用下一个拦截器,对response进行处理,返回给上一个拦截器

BridgeInterceptor补充请求头信息的拦截器

1 负责将用户构建的一个Request请求转化为能够进行网络访问的请求
2 将这个符合网络请求的Request进行网络请求
3 将网络请求回来的响应Response转化为用户可用的Response

CacheInterceptor缓存拦截器

ConnectInterceptor

1 ConnectInterceptor获取Interceptor传过来的StreamAllocation,streamAllocation.newStream()
2 将刚才创建的用于网络IO的RealConnection对象以及对于与服务器交互最为关键的HttpCodec等对象传递给后面的拦截器

1 弄一个RealConnection对象
2 选择不同的链接方式
3 CallServerInterceptor

CallServerInterceptor

源码地址:

https://github.com/wxyass/OkHttpTest

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注