关于Okhttp(一)
简介
Okhttp是square公司推出的一款Android和Java网络请求库,当前推出了Okhttp3,在原来的基础上做了很大改进,也是Android目前最流行的网络库之一,本系列文章就是基于最新的来剖析。鉴于能力以及代码的优化改动,文中如有不足之处还望指教,谢谢。
特点
Http/2支持多路复用
采用连接池减少请求延时
支持GZIP压缩
响应缓存
支持websocket
多ip切换(连接失败并且服务器有多ip)
基本使用
Android使用注意申请网络权限,同时不能在主线程请求
设置缓存
设置缓存超级简单,只需在创建OkHttpClitent时定义缓存目录即可,同时它是基于http的方式来处理缓存,后面会详细解释
OkHttpClient okHttpClient = new OkHttpClient.Builder() // 大小是bytes .cache(new Cache(new File("xx/xxx/"), 20 * 1024)) .build();
Okhttp仅支持get请求缓存哦,其他请求方式需要自己实现
超时设置
okhttp超时分为连接超时、读取超时、写入超时
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的保存也提供了快捷方式,当然也可以通过拦截器自己实现
OkHttpClient okHttpClient = new OkHttpClient.Builder() .cookieJar(new CookieJar() { @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { // 保存cookie通常使用SharedPreferences } @Override public List<Cookie> loadForRequest(HttpUrl url) { // 从保存位置读取,注意此处不能为空,否则会导致空指针 return new ArrayList<>(); } }) .build();
添加拦截器
okhttp3的实现使用的是链式的拦截器,同时也开放了自定义拦截器接口
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,只要设置好证书即可
OkHttpClient okHttpClient = new OkHttpClient.Builder() // 创建一个证书工厂 .sslSocketFactory(SSLSocketFactory, X509TrustManager) .build();
GET
// 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.创建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.创建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.创建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请求,握手成功后,转换协议保持长连接,类似心跳
// 方法可以选择实现 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)中添加如下语句:
总结
Okhttp3已经成为android必备的网络请求库,同时也是比较好用的库,对于更多Okhttp的实现细节,请看下节
作者:lowett