关于Okhttp(一)


简介

Okhttp是square公司推出的一款Android和Java网络请求库,当前推出了Okhttp3,在原来的基础上做了很大改进,也是Android目前最流行的网络库之一,本系列文章就是基于最新的来剖析。鉴于能力以及代码的优化改动,文中如有不足之处还望指教,谢谢。

特点

  1. Http/2支持多路复用
  2. 采用连接池减少请求延时
  3. 支持GZIP压缩
  4. 响应缓存
  5. 支持websocket
  6. 多ip切换(连接失败并且服务器有多ip)

基本使用

Android使用注意申请网络权限,同时不能在主线程请求

设置缓存

设置缓存超级简单,只需在创建OkHttpClitent时定义缓存目录即可,同时它是基于http的方式来处理缓存,后面会详细解释

1
2
3
4
OkHttpClient okHttpClient = new OkHttpClient.Builder()
  // 大小是bytes
               .cache(new Cache(new File("xx/xxx/"), 20 * 1024))
               .build();

Okhttp仅支持get请求缓存哦,其他请求方式需要自己实现

超时设置

okhttp超时分为连接超时、读取超时、写入超时

1
2
3
4
5
6
OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .connectTimeout(10, TimeUnit.SECONDS)
                .pingInterval(10, TimeUnit.SECONDS) // websocket 轮训间隔
                .build();

Cookie保存

Cookie的保存也提供了快捷方式,当然也可以通过拦截器自己实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
OkHttpClient okHttpClient = new OkHttpClient.Builder()
              .cookieJar(new CookieJar() {
                  @Override
                  public void saveFromResponse(HttpUrl url, List cookies) {
				// 保存cookie通常使用SharedPreferences
                  }

                  @Override
                  public List loadForRequest(HttpUrl url) {
                    // 从保存位置读取,注意此处不能为空,否则会导致空指针
                      return new ArrayList<>();
                  }
              })
              .build();

添加拦截器

okhttp3的实现使用的是链式的拦截器,同时也开放了自定义拦截器接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
OkHttpClient okHttpClient = new OkHttpClient.Builder()
  // 此种拦截器将会在请求开始的时候调用
        .addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
              // 略
                return null;
            }
        })
  // 连接成功,读写数据前调用
        .addNetworkInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
              // 略
                return null;
            }
        })
        .build();

Https

okhttp3完全支持https,只要设置好证书即可

1
2
3
4
OkHttpClient okHttpClient = new OkHttpClient.Builder()
		// 创建一个证书工厂
        .sslSocketFactory(SSLSocketFactory, X509TrustManager) 
        .build();

GET

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 1.创建一个OkHttpClient,通常是单例,如果要自定义一些属性那就要用内部的Builder来构造
/**
*   OkHttpClient okHttpClient = new OkHttpClient.Builder()
                        .addInterceptor() //请求前的拦截器
                        .addNetworkInterceptor() // 网络拦截器
                        .cache() // 缓存目录
                        .connectTimeout() // 连接超时
                        .cookieJar() // cookie的读取,保存,需要自己实现
                        .sslSocketFactory() // https证书
                        ...略...
                        .build();
*/
OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  // 2. 创建一个request,包含请求地址、请求参数、请求头等
  Request request = new Request.Builder()
      .url(url)
      .build();

  // 3. 同步请求,得到响应
  Response response = client.newCall(request).execute();
  return response.body().string();
}

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
// 1.创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .build();

// 2.创建请求参数,注意,此处有多种方式
RequestBody requestBody = new FormBody.Builder()
        .add("param", "value")
        .build();
// 3.创建请求request
Request request = new Request.Builder()
        .url("https://wwww.xxx.com")
        .post(requestBody)
        .build();
// 4.发起请求,此处使用的是异步请求,按需要选择同步或异步
okHttpClient.newCall(request)
        .enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
// 5.处理相响应
            }
        });

上传文件

上传文件本质上是post请求,区别是在参数类型上

不要忘记权限,6.0(api23)动态权限

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
// 1.创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .build();

// 不同点
// 2.创建请求参数,设置对应的参数类型即可
 RequestBody requestBody = RequestBody.create(MediaType.parse("text/x-markdown; charset=utf-8"), new File("xxx.txt"));
// 3.创建请求request
Request request = new Request.Builder()
        .url("https://wwww.xxx.com")
        .post(requestBody)
        .build();
// 4.发起请求
okHttpClient.newCall(request)
        .enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
// 5.处理相响应
            }
        });

Multipart文件

multipart文件同上传文件,区别是它可以同时有字符参数,也可以有文件

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
// 1.创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .build();

// 不同点
// 2.创建请求参数,设置对应的参数类型即可
 RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("fileParam", "xxx.png", RequestBody.create(MediaType.parse("image/png"), new File("xxx/xxx.png")))
                .addFormDataPart("param", "value")
                .build();
// 3.创建请求request
Request request = new Request.Builder()
        .url("https://wwww.xxx.com")
        .post(requestBody)
        .build();
// 4.发起请求
okHttpClient.newCall(request)
        .enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
// 5.处理相响应
            }
        });

Websocket

okhttp3支持websocket,如果不了解请自行搜索,简易推送,轮训都可以使用。

websocket协议首先会发起http请求,握手成功后,转换协议保持长连接,类似心跳

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
32
33
34
35
36
37
// 方法可以选择实现
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .build();
Request request = new Request.Builder()
        .url("https://wwww.xxx.com")
        .build();
okHttpClient.newWebSocket(request, new WebSocketListener() {
    @Override
    public void onMessage(WebSocket webSocket, String text) {
        super.onMessage(webSocket, text);
      // 当收到文本消息
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
       // 连接成功
    }

    @Override
    public void onMessage(WebSocket webSocket, ByteString bytes) {
        super.onMessage(webSocket, bytes);
       // 收到字节消息,可转换为文本
    }

    @Override
    public void onClosed(WebSocket webSocket, int code, String reason) {
        super.onClosed(webSocket, code, reason);
       // 连接被关闭
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        super.onFailure(webSocket, t, response);
       // 连接失败
    }
});

混淆

在混淆文件(proguard-rules.pro)中添加如下语句:

1
-dontwarn okhttp3.**

总结

Okhttp3已经成为android必备的网络请求库,同时也是比较好用的库
















你可能感兴趣的:(关于Okhttp(一))