github 地址: https://github.com/square/okhttp

1.OkHttp 特点

OkHttp 是一个高效的 Http 客户端,特点如下:

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

2.GET 使用方法

  • 同步请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
    .url(url)
    .build();//http 请求
    Response response = client.newCall(request).execute(); //请求的响应
    ResponseBody responseBody = response.body();//响应体
    //responseBody.body().string();//字符串表示、占内存
    //responseBody.body().bytes();//字节数组表示、占内存
    //responseBody.body().charStream();//字符流表示 (超过 1M)
    //responseBody.body().byteStream();//字节流表示 (超过 1M)
  • 异步请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
    .url(url)
    .build();//http 请求
    Response response = client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
    }
    }); //返回的响应

###3. POST 使用方法

  • MediaType 类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
    * "application/x-www-form-urlencoded",是默认的MIME内容编码类型,一般可以用于所有的情况,但是在传输比较大的二进制或者文本数据时效率低。
    这时候应该使用"multipart/form-data"。如上传文件或者二进制数据和非ASCII数据。
    */
    public static final MediaType MEDIA_TYPE_NORAML_FORM = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
    //既可以提交普通键值对,也可以提交(多个)文件键值对。
    public static final MediaType MEDIA_TYPE_MULTIPART_FORM = MediaType.parse("multipart/form-data;charset=utf-8");
    //只能提交二进制,而且只能提交一个二进制,如果提交文件的话,只能提交一个文件,后台接收参数只能有一个,而且只能是流(或者字节数组)
    public static final MediaType MEDIA_TYPE_STREAM = MediaType.parse("application/octet-stream");
    public static final MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain;charset=utf-8");
    public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json;charset=utf-8");
  • Post 提交 String

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    OkHttpClient client = new OkHttpClient();
    Request request =new Request.Builder().url(url)
    .post(RequestBody.create(MEDIA_TYPE_TEXT,"提交内容"))//指定提交方式 Post
    .build();
    try {
    Response response = client.newCall(request).execute();
    } catch (IOException e) {
    e.printStackTrace();
    }

  • FormBody 提交表单

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    OkHttpClient client = new OkHttpClient();
    RequestBody formBody = new FormBody.Builder()
    .add("key","value")//键值对使用
    .build();
    Request request =new Request.Builder()
    .url(WEATHER_URL)
    .post(formBody)
    .build();
    try {
    Response response = client.newCall(request).execute();
    } catch (IOException e) {
    e.printStackTrace();
    }

  • Post 提交流

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    OkHttpClient client = new OkHttpClient();
    File file = new File("文件路径");
    final FileInputStream fileInputStream=new FileInputStream(file);
    RequestBody requestBody = new RequestBody() {
    @Nullable
    @Override
    public MediaType contentType() {
    return MEDIA_TYPE_TEXT;//指定文件类型
    }
    @Override
    public void writeTo(BufferedSink sink) throws IOException {
    OutputStream outputStream = sink.outputStream();//获取 outputStream 、sink也可以直接写入
    int length;
    byte[] buffer = new byte[1024];
    while((length = fileInputStream.read(buffer)) != -1){
    outputStream.write(buffer,0,length);//写入流
    }
    }
    };
    Request request =new Request.Builder()
    .url(url)
    .post(requestBody)
    .build();
    try {
    Response response = client.newCall(request).execute();
    } catch (IOException e) {
    e.printStackTrace();
    }
  • Post 提交文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    OkHttpClient client = new OkHttpClient();
    File file = new File("文件路径");
    Request request =new Request.Builder()
    .url(url)
    .post(RequestBody.create(MEDIA_TYPE_TEXT,file))//提交文件
    .build();
    try {
    Response response = client.newCall(request).execute();
    } catch (IOException e) {
    e.printStackTrace();
    }
  • MultipartBody 提交分块请求(多类型字段)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    OkHttpClient client = new OkHttpClient();
    RequestBody requestBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("title","Square Logo")//string 字段
    .addFormDataPart("image","logo-square.png",RequestBody.create(MediaType.parse("image/png"),new File("website/static/logo-square.png")))//图片
    .build();//构建
    Request request =new Request.Builder()
    .addHeader("Authorization","Client-ID " + "...")//认证头
    .url(WEATHER_URL)
    .post(requestBody)//提交文件
    .build();
    try {
    Response response = client.newCall(request).execute();
    } catch (IOException e) {
    e.printStackTrace();
    }
  • Post 提交 json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    OkHttpClient client = new OkHttpClient();
    Request request =new Request.Builder().url(url)
    .post(RequestBody.create(MEDIA_TYPE_JSON,"提交内容"))//指定提交方式 Post
    .build();
    try {
    Response response = client.newCall(request).execute();
    } catch (IOException e) {
    e.printStackTrace();
    }
    1
    2
    3
    4
    ### 4.OkHttp 设置
    1.设置超时、缓存

    File sdcache = getExternalCacheDir();//缓存路径
    int cacheSize = 10 1024 1024;//缓存时间
    OkHttpClient client = new OkHttpClient.Builder()

    .connectTimeout(10, TimeUnit.SECONDS)//设置超时 连接
    .readTimeout(10,TimeUnit.SECONDS)//设置超时 读入
    .writeTimeout(10,TimeUnit.SECONDS)//设置超时 写入
    .cache(new Cache(sdcache.getAbsoluteFile(),cacheSize))//设置缓存
    .build();
    
    1
    2
    2.取消请求

    call.cancel();//取消请求 call 单独提出来
    client.dispatcher().cancelAll();//取消所有请求

    1
    2