zoukankan      html  css  js  c++  java
  • okhttp

    OkHttp 封装了请求和缓存和缓存

    OkHttp是一个相对成熟的解决方案,据说Android4.4的源码中可以看到HttpURLConnection已经替换成OkHttp实现了。所以我们更有理由相信OkHttp的强大。

    OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。

    使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和HttpURLConnection一样的API。如果你用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。

    OkHttp 和 fresco  retrofit 等第三方库能很好的衔接。

    Okhttp作为HTTP引擎,retrofit作为restful业务架构实现;目前retrofit的restful风格规范是趋势。

    OkHttp是一个高效的Http客户端

    1. 支持HTTP2/SPDY黑科技
    2. socket自动选择最好路线,并支持自动重连
    3. 拥有自动维护的socket连接池,减少握手次数
    4. 拥有队列线程池,轻松写并发
    5. 拥有Interceptors轻松处理请求与响应(比如透明GZIP压缩,LOGGING)
    6. 基于Headers的缓存策略

    注:什么是SPDY

    SPDY(读作“SPeeDY”)是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。新协议的功能包括数据流的多路复用、请求优先级以及HTTP报头压缩。谷歌表示,引入SPDY协议后,在实验室测试中页面加载速度比原先快64%。中文名:spdy协议,目前SPDY已经被Http/2代替,google已经宣布要移除SPDY;

    主要对象

    • Connections: 对JDK中的socket进行了引用计数封装,用来控制socket连接
    • Streams: 维护HTTP的流,用来对Requset/Response进行IO操作
    • Calls: HTTP请求任务封装
    • StreamAllocation: 用来控制Connections/Streams的资源分配与释放

    工作流程的概述

    当我们用OkHttpClient.newCall(request)进行execute/enenqueue时,实际是将请求Call放到了Dispatcher中,okhttp使用Dispatcher进行线程分发,它有两种方法,一个是普通的同步单线程;另一种是使用了队列进行并发任务的分发(Dispatch)与回调,我们下面主要分析第二种,也就是队列这种情况,这也是okhttp能够竞争过其它库的核心功能之一; 

    Socket管理(StreamAllocation)

    经过上一步的分配,我们现在需要进行连接了。我们目前有封装好的Request,而进行HTTP连接需要进行Socket握手,Socket握手的前提是根据域名或代理确定Socket的ip与端口。这个环节主要讲了http的握手过程与连接池的管理,分析的对象主要是StreamAllocation。

    Githug:  https://github.com/square/okhttp

    wiki:https://github.com/square/okhttp/wiki

    中文翻译wiki

    OKHttp源码解析

    配置方法:

    注意:okhttp内部依赖okio,别忘了同时导入okio

    (1)Android Studio:

    1 compile 'com.squareup.okhttp:okhttp:2.4.0'

    导入okio:

    1 compile 'com.squareup.okio:okio:1.5.0'

    (2)Eclipse:

    可以下载最新的jar okhttp he latest JAR ,添加依赖就可以用了

    最新的jar地址:okio the latest JAR

    使用:

    1 //创建okHttpClient对象
    2 OkHttpClient mOkHttpClient = new OkHttpClient();
    3 // 创建Request.Builder  post请求方式
    4 Request.Builder builder = new Request.Builder().post()
    5                 .url("https://github.com/hongyangAndroid");
    6 //创建一个Request
    7 final Request request = builder.build();
    8 //通过请求request,构造出call
    9 Call call = mOkHttpClient.newCall(request); 

    (1)Request.Builder

    通过Request.Builder设置更多的参数比如:

    (1) 添加请求头header:

    如果它本身存在值,在添加新的value之前,他们会被移除。使用addHeader(name, value)来添加头部不需要移除当前存在的headers。

    1 builder.addHeader("SYSVERSION",  "1.01");

    当写请求头,构造时用header(name, value)来为唯一出现的name设置value。

    1 Request.Builder builder = new Request.Builder().post()
    2                  .url("https://github.com/hongyangAndroid")
    3                  .header("Cookie", "OkHttpUser");

    (2)添加method

    请求携带参数:

    post方式:

    发布表单参数

     1 String url = url;
     2 // 创建builder
     3 FormBody.Builder builder = new FormBody.Builder();
     4 requestBody.add("user", "charles");
     5 requestBody.add("age", "12");
     6 // 创建RequestBody
     7 RequestBody requestBody = builder.build();
     8 
     9 Request request = new Request.Builder().post(requestBody ).url(url).build();
    10 Response response = mOKHttpClient.newCall(request).execute();

    发布multipart请求

    MultipartBody.Builder可以构建与HTML文件上传表单兼容的复杂请求主体。例如文件上传

    视频类:MediaType.parse("application/octet-stream")

     1 File file = new File(Environment.getExternalStorageDirectory(), "about.jpg");
     2 
     3 RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);
     4 
     5 RequestBody requestBody = new MultipartBuilder()
     6      .type(MultipartBuilder.FORM)
     7      .addPart(Headers.of(
     8           "Content-Disposition", 
     9               "form-data; name="username""), 
    10           RequestBody.create(null, "charles"))
    11      .addPart(Headers.of(
    12          "Content-Disposition", 
    13          "form-data; name="imagefile"; 
    14          filename="aboutApp.jpg""), fileBody)
    15      .build();
    16 
    17 Request request = new Request.Builder()
    18     .url("http://.../fileUpload")
    19     .post(requestBody)
    20     .build();
    21 
    22 Reponse reponse = mOkHttpClient.newCall(request).execute();

    get方式:

    1 String url = url + "?" + "user=charles" + "&age=12" 
    2 Request request = new Request.Builder().get().url(url).build();
    3 Response response = mOKHttpClient.newCall(request).execute();

    执行call:

    (1)异步

    调用call.enqueue,将call加入调度队列,等待任务执行完成,在Callback中即可得到结果。

     1 // 异步执行call
     2 call.enqueue(new Callback()
     3         {
     4             @Override
     5             public void onFailure(Request request, IOException e)
     6             {
     7             }
     8 
     9             @Override
    10             public void onResponse(final Response response) throws IOException
    11             {
    12                  String htmlStr =  response.body().string();// 当前线程不是ui线程
    13             }
    14         });  

    (2)同步,阻塞方式:

    1 Response response = call.execute();

    Response:

    (1)返回字符串,通过response.body().string()获取;

    (2)返回二进制字节数组,通过response.body().bytes()获取

    (3)返回inputStream,通过response.body().byteStream()获取 (支持大文件下载);

  • 相关阅读:
    Building a flexiable renderer
    Indirect Illumination in mental ray
    我的心情
    Cellular Automata
    Subsurface Scattering in mental ray
    Shader Types in mental ray
    BSP Traversal
    我的渲染器终于达到了MR的速度
    How to handle displacement and motion blur
    说明
  • 原文地址:https://www.cnblogs.com/CharlesGrant/p/6512712.html
Copyright © 2011-2022 走看看