OkHttp 用法及解析

1、OkHttp介绍  

       OkHttp是Square公司开发的Http通用库,支持HTTP和HTTPP/2,用于Android和Java应用开发。OkHttp是一款高效的HTTP客户端,支持同一个地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。

       HttpURLConnection 是一个多用途、轻量级的http客户端,它对网络请求的封装没有HttpClient彻底,api比较简单,用起来没有那么方便。虽然易于扩展但是封装起来相对困难,在Android2.2中存在关闭Inputstream 时连接池失效等问题,通常需要禁用连接池来解决。Android4.4原生的HttpURLConnection底层已经替换成了OkHttp实现

       HttpClient时Apache的一个三方网络框架,网络请求做了完善的封装,api众多,用起来比较方便,开发快。使用比较稳定,但是正是由于其api众多,使得很难在不破坏兼容性的情况下对其进行扩展。所以android5.0中被废弃,6.0逐渐删除,全面转向使用OkHttp.

       目前有很多知名的Android三方框架都使用OKHttp作为网络连接的默认基栈,例如Volley,Gilde,Retrofit等。

2、基本使用

   (1)、在项目中添加对OkHttp的依赖。

          在需要使用OkHttp的模块的build。gradle文件中,添加如下依赖库。(版本号可能存在变更)

dependencies {
    compile 'com.squareup.okhttp3:okhttp:3.6.0'
}

  (2)、初始化

          OkHttp框架的核心类是OkHttpClient,此类可直接实例化。由于OkHttpClient 内部处理了并发,多线程和Socket重用等问题,为了节省资源,整个应用中使用一个OkHttpClient对象即可,可以对它做Singleton(单例)封装。

  OkHttpClient client=new OkHttpClient();

(3)、OkHttp请求构建

           代表Http请求的类是Request,该类使用构造器模式,最简单的构造get(默认是get请求体)请求如下。

 Request request=new Request.Builder()
                .url("url")
                .build();

           构造post请求,在构建Request时添加请求体 RequestBody示例如下:

  RequestBody body=new FormBody.Builder()
              .add("name","张飞")
              .add("age","12")
              .build();
 Request request=new Request.Builder() .post(body) .url(url) .build();
 

(4)、OkHttp请求的发送

          请求的发送有两种形式:一种是直接同步执行,阻塞调用线程,直接返回结果;(不推荐,Android中可能阻塞UI线程)

                                               另一种是通过队列异步执行,不阻塞调用线程,通过回调方法返回结果。如下所示:

同步执行:

 
//如果返回null,代表超时或没有网络连接
 Response response=client.newCall(request).execute();

异步回调:

  
client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //超时或没有网络连接
                //注意:这里是后台线程!(更新UI需要切换到UI线程)
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //成功
                //注意:这里是后台线程!(更新UI需要切换到UI 线程)
            }
        });

以上简单介绍OkHttp使用,最后会附上源码


3、OkHttp详解

   Request、Response、Call 基本概念

    上面的代码中涉及到几个常用的类:Request、Response和Call。下面分别介绍:

   Request

    每一个HTTP请求包含一个URL、一个方法(GET或POST或其他)、一些HTTP头。请求还可能包含一个特定内容类型的数据类的主体部分。

   Response

    响应是对请求的回复,包含状态码、HTTP头和主体部分。

   Call 模型

     OkHttp使用Call抽象出一个满足请求的模型,尽管中间可能会有多个请求或响应。执行Call有两种方式,同步或异

     Http客户端的任务是处理请求和响应,这说起来简单,但实际过程很复杂。

            请求:Http请求包含URL,请求方法(例如GET或者POST),请求头。还可能包含请求体,可以是数据流也可以是指定的内容类别。

            响应:用一个响应码来回应请求(例如200代表成功,404代表页面未找到),响应头和响应体。


     请求的重写

      为了保证正确性和传输效率,OkHttp会在发送你的请求之前重写它,例如:如下

      OkHttp可能会添加原始请求中缺失的头部信息,包括Content-Length【内容长度】、Transfer-Encoding(传输编码),User-Agent(用户代理) ,Host (主机), Connecton(连接)和 Content-Type(内容类型)。

      为了实现透明的响应压缩(transparent response compression),OkHttp会增加Accept-Encoding头信息。

      如果你收到了cookie,OkHttp会增加Cookie 头信息。

      某些请求可能会对响应做缓存。如果被缓存的响应不是最新的,OkHttp能做一个有条件的GET请求来下载更新后的响应。此功能需要添加 If - Modified -Since和 If -Node-Match等头信息。


      响应的重写

       如果使用了透明压缩,OkHttp 会去掉对响应Content -Encoding 和 Content - Length头信息,因为他们不能应用于解压后的响应体。

       如果有条件的GET成功了,网络侧的响应和缓存的响应会被自动合并。

   

       重定向

        如果你请求的URL被移动了,服务器会返回类似于302这样的响应码,来指明新的URL。OkHttp能跟随新的URL,获取到最终的响应。(用户只需发送一次Okhttp请求,由OkHttp 负责完成重定向请求,并获得最终请求结果)

请求的重试

有时会发生连接失败:可能网络连接状况不好,或者服务器不可达。OkHttp会自动使用不同的路由来重试请求。

Call模型

由于以上的重写,重定向和重试等操作,你的一个简单请求可能会产生多个请求和响应。OkHttp使用Call这个概念对此来建模:不论为了满足你的请求任务,中间做了多少次请求和响应,都算作一个Call。

Call有两种方式来执行:

      同步方式:你的线程会被阻塞,直到响应可读。

      异步方式:你在任意线程将请求排队,当响应可读时,会在另一个线程拿到回调。

Call的取消

使用Call.cancel()来停止一个执行中的请求。如果线程正在请求或读取响应,则会收到IOException。使用此方法,在一个Call已经不需要时取消它,可以节省网络流量。

Call可以在任意线程取消,如果请求没有完成,调用取消方法会导致请求失败,读写请求体和响应体的代码会产生IOException。


拦截器

OkHtttp在请求响应过程中可以添加拦截器,拦截器和响应的数据等。

需要添加依赖
//日志拦截器 
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'

用法
 //初始化日志拦截器 
 HttpLoggingInterceptor interceptor=new HttpLoggingInterceptor();

 //设置拦截级别 (NONE:没有日志; BASIC:基本 HEADERS  ;BODY )
 interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);

 //添加拦截器 
 OkHttpClient client=new OkHttpClient().newBuilder().addInterceptor(interceptor).build();
 


         

          



 


         

    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值