OkHttp使用介绍
来源:互联网 发布:java有多少关键字 编辑:程序博客网 时间:2024/06/15 05:49
最近对应用的网络模块进行重构,从原有HttpClient切换到OkHttp;在此对OkHttp的使用做一个简单的总结,方便后续查阅。
官网地址:http://square.github.io/okhttp/
GitHub地址:https://github.com/square/okhttp
OkHttp框架是一个基于http协议(http协议介绍)的网络请求框架,实现的主要功能,
- 网络请求的调度
- 请求线程的复用
- 请求连接的复用
- 缓存策略的实现
- 网络路由的实现
- 拦截器
本文站在Http的角度对OkHttp的使用做一个简单的介绍。
OkHttp的配置
gradle配置
compile 'com.squareup.okhttp3:okhttp:3.8.1'
ProGuard配置
-dontwarn okio.**-dontwarn javax.annotation.Nullable-dontwarn javax.annotation.ParametersAreNonnullByDefault
Request
每一个Http请求都包含一个请求行和请求头,也可能包含请求正文。在OkHttp中通过Request类表示一个http请求,采用构建者设计模式通过一个Request.Builder来构建一个Request.
public final class Request { final HttpUrl url; final String method; final Headers headers; final RequestBody body; final Object tag; public static class Builder { HttpUrl url; String method; Headers.Builder headers; RequestBody body; public Request build() { if (url == null) throw new IllegalStateException("url == null"); return new Request(this); } } ...省略代码... }
通过Builder构建一个Request
Request.Builder builder = new Request.Builder();...构建步骤url/method等...Request request = builder.build();
请求行
builder.url(url);//设置urlbuilder.get();//设置请求方法为GET,也可以通过builder.method("GET",null)进行设置
请求头Headers
builder.addHeader("User-Agent","android 8.0");//设置User-Agentbuilder.removeHeader("Cache-Control");//从Headers中移除Cache-Control
请求正文RequestBody
//请求正文为String类型String content = "XXXXXXXXXXXXX";//请求正文内容RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"),content);//请求正文为byte类型byte[] bytes;//请求正文内容,需要初始化复制哈RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),bytes);//请求正文为File类型(一般指上传文件之类的)File file = new File("pathXXX");RequestBody requestBody = RequestBody.create(MediaType.parse(" image/png"),bytes);
构建一个完整的请求Request
String content = "构建一个完整的OkHttp Request";//构建RequestBodyRequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"),content);Request.Builder builder = new Request.Builder();//设置url、method、header等builder.url("http://XXX").post(requestBody).addHeader("Cache-Control","no-cache");//构建RequestRequest request = builder.build();
Call
在OkHttp中,通过Call来执行一个Request,其真正的实现在RealCall中实现,具体逻辑到后面的源码分析阶段在分析。
OkHttpClient okHttpClient = new OkHttpClient();Call call = okHttpClient.newCall(request);Response response = call.execute();
Call提供了同步和异步两种执行方式。
Call异步执行
Call异步执行,调用enqueue(callback)函数,将请求加入到请求队列当中去,通过callback来监控请求的执行进度
OkHttpClient okHttpClient = new OkHttpClient();Call call = okHttpClient.newCall(request);call.enqueue(new okhttp3.Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { }});
onFailure:请求失败,这里的失败是指OkHttp执行失败,而不是服务端对请求返回code表示失败。
onResponse:表示与服务端请求通信成功,通过解析返回的response来解析服务端返回的具体结果
Call同步执行
Call同时提供了同步执行,调用execute()函数进行同步执行,同步执行会阻塞当前的线程,直到请求结果返回,因此要注意不要在UI线程中执行。execute()的返回值是Response;若请求失败为null,请求成功则对response进行解析。
OkHttpClient okHttpClient = new OkHttpClient();Call call = okHttpClient.newCall(request);Response response = call.execute();//对response进行解析
Call取消请求
Call同时支持取消,对正在执行的请求进行取消操作
OkHttpClient okHttpClient = new OkHttpClient();Call call = okHttpClient.newCall(request);Response response = call.execute();//突然不想执行了call.cancel();
执行cancel()后,若是通过enqueue(callback)进行异步执行,则会调用callback的onFailure;若是同步执行,call.execute()返回的结果为null.
Response
Http请求与服务端正常通信之后会对客户端进行响应,在OkHttp中,将服务端的响应封装在Response中返回给上层,上层通过解析Response来获取服务端返回的数据。
public final class Response implements Closeable { final Request request;//对应的请求 final Protocol protocol; final int code; final String message; final Handshake handshake; final Headers headers; final ResponseBody body; final Response networkResponse; final Response cacheResponse; final Response priorResponse; final long sentRequestAtMillis;//发送请求的时间 final long receivedResponseAtMillis;//接受服务端数据的时间...省略代码若干...}
状态行
Response中的code和message分别表示状态行的状态码与状态码描述
final int code; final String message;
判断服务端是否成功响应客户端的请求有两种方式:
第一种:通过response.code的值,来表示判断此次请求服务端是否正常响应
第二种:调用response.isSuccessful(),其内部也是通过比较code的值,在[200,300)之间返回true
响应头
Response将响应头的信息封装在Headers中,通过header(name)读取响应头中的信息
Response response = call.execute();//读取Cache-Control信息String cacheControl = response.header("Cache-Control");//读取Expires信息String expires = response.header("Expires");
响应正文
Response将响应正文的信息封装在ResponseBody中,通过ResponseBody读取响应正文中的信息,读取信息有三种方式,
Response response = call.execute();//第一种方式:通过bytes()函数获取字节数组byte[] data = response.body().bytes();//第二种方式:通过string()获取字符串String result = response.body().string();//第三种方式:通过byteStream()获取InputStream,从流中读取数据InputStream stream = response.body().InputStream();
注意事项:
1.第一种方式获取字节数组,会将整个响应正文都加载到内存;但对于比较大的响应正文(例如100M的文件),很有可能会导致OutOfMemoryError,此种情况下应该使用InputStream()代替。
2.第二种方式是直接将响应正文转化为字符串返回,但是对于非字符串或者某些加密过的字符串,则不能直接调用byte()来代替。同时所有数据也会被加载到内存当中,存在第一种方式引发OutOfMemoryError的可能。
3.第三种方式一般适合于文件等比较大,不适合全部都加载到内存的响应正文,例如文件下载等。
完整代码片段示例
抓取https://www.baidu.com/的内容
Request.Builder builder = new Request.Builder();Request request = builder.url("https://www.baidu.com/").get().build();OkHttpClient okHttpClient = new OkHttpClient();Call call = okHttpClient.newCall(request);call.enqueue(new okhttp3.Callback() { @Override public void onFailure(Call call, IOException e) { //抓取失败处理 } @Override public void onResponse(Call call, Response response) throws IOException { //判断是否抓取成功 if(response != null && response.isSuccessful()) { String content = response.body().string(); //content为百度主页的内容 } }});
若要了解文件的上传下载、表单等等的实现,可以参考OkHttp在Github上的WiKi。
- OkHttp使用介绍
- OkHttp的使用介绍
- OkHttp使用介绍
- OkHttp使用介绍
- OkHttp使用介绍
- okHttp使用介绍
- OkHttp使用介绍
- OkHttp使用介绍
- OkHttp使用介绍 - 冷耳听语
- OkHttp使用介绍
- OkHttp使用介绍
- OKHttp使用简单介绍,实用教程
- 简单的OkHttp使用介绍
- OkHttp使用介绍 和 使用进阶
- Http请求框架 okHttp 简单使用介绍
- Okhttp的简单介绍和使用(一)
- Android OKHttp介绍与使用(一)
- Android OKHttp介绍与使用(二)
- Python 3从入门到精通9- 判断两个字符串是否相等,是否包含关系
- Unity Shader入门精要笔记(十一):基础单张纹理
- 【BUG笔记】执行exe文件时报错“应用程序无法正常启动(0x000007b)”
- 【OpenCV入门指南】第七篇 线段检测与圆检测
- 备份spring学习项目目录
- OkHttp使用介绍
- SSH免密钥登录
- 练习1-15 重写温度转换程序
- dubbox的学习之路1(实现原理,特性、安装部署、负载均衡)
- <input id="pjdxid_1" type="hidden" value="${fwpj.CPjdxId }" />中hidden的用法
- 【OpenCV入门指南】第八篇 灰度直方图
- MySQL在本机无法基于localhost访问的问题解决
- UE4复刻过程(一)-UI,UMG的复刻
- mybatis常用jdbcType数据类型