OkHttp的理解和使用
OkHttp
1、什么是OkHttp
1、网络请求发展
HttpURLConnection—>Apache HTTP Client—>Volley—->okHttp
2、项目开源地址
https://github.com/square/okhttp
3、OkHttp是什么
- OKhttp是一个网络请求开源项目,Android网络请求轻量级框架,支持文件上传与下载,支持https。
2、OkHttp的作用
OkHttp是一个高效的HTTP库:
- 支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上一次性发送多个请求来发送或接收数据
- 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时
- 支持GZIP, 可以压缩下载体积
- 响应缓存可以直接避免重复请求
- 会从很多常用的连接问题中自动恢复
- 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OkHttp会自动尝试下一个IP OkHttp还处理了代理服务器问题和SSL握手失败问题
优势
- 使用 OkHttp无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果您用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块
3、Okhttp的基本使用
Okhttp的基本使用,从以下五方面讲解:
- 1.Get请求(同步和异步)
- 2.POST请求表单(key-value)
- 3.POST请求提交(JSON/String/文件等)
- 4.文件下载
- 5.请求超时设置
加入build.gradle
compile 'com.squareup.okhttp3:okhttp:3.6.0'
3.1、Http请求和响应的组成
http请求
所以一个类库要完成一个http请求, 需要包含 请求方法, 请求地址, 请求协议, 请求头, 请求体这五部分. 这些都在okhttp3.Request的类中有体现, 这个类正是代表http请求的类. 看下图:
其中HttpUrl类
代表请求地址, String method
代表请求方法, Headers
代表请求头, RequestBody
代表请求体. Object tag
这个是用来取消http请求的标志, 这个我们先不管.
http响应
响应组成图:
可以看到大体由应答首行, 应答头, 应答体
构成. 但是应答首行表达的信息过多, HTTP/1.1表示访问协议, 200是响应码, OK是描述状态的消息.
根据单一职责, 我们不应该把这么多内容用一个应答首行来表示. 这样的话, 我们的响应就应该由访问协议, 响应码, 描述信息, 响应头, 响应体来组成.
3.2、OkHttp请求和响应的组成
OkHttp请求
构造一个http请求, 并查看请求具体内容:
final Request request = new Request.Builder().url("https://github.com/").build();
我们看下在内存中, 这个请求是什么样子的, 是否如我们上文所说和请求方法, 请求地址, 请求头, 请求体
一一对应.
OkHttp响应
OkHttp库怎么表示一个响应:
可以看到Response类
里面有Protocol
代表请求协议, int code
代表响应码, String message
代表描述信息, Headers
代表响应头, ResponseBody
代表响应体. 当然除此之外, 还有Request
代表持有的请求, Handshake
代表SSL/TLS
握手协议验证时的信息, 这些额外信息我们暂时不问.
有了刚才说的OkHttp响应的类组成, 我们看下OkHttp请求后响应在内存中的内容:
final Request request = new Request.Builder().url("https://github.com/").build();
Response response = client.newCall(request).execute();
3.3、GET请求同步方法
同步GET的意思是一直等待http请求, 直到返回了响应. 在这之间会阻塞进程, 所以通过get不能在Android的主线程中执行, 否则会报错.
对于同步请求在请求时需要开启子线程,请求成功后需要跳转到UI线程修改UI。
public void getDatasync(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象
Request request = new Request.Builder()
.url("http://www.baidu.com")//请求接口。如果需要传参拼接到接口后面。
.build();//创建Request 对象
Response response = null;
response = client.newCall(request).execute();//得到Response 对象
if (response.isSuccessful()) {
Log.d("kwwl","response.code()=="+response.code());
Log.d("kwwl","response.message()=="+response.message());
Log.d("kwwl","res=="+response.body().string());
//此时的代码执行在子线程,修改UI的操作请使用handler跳转到UI线程。
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
此时打印结果如下:
response.code()==200;
response.message()OK;
res{“code”:200,“message”:success};
OkHttpClient
实现了Call.Factory
接口, 是Call的工厂类, Call负责发送执行请求和读取响应
.
Request代表Http请求, 通过Request.Builder
辅助类来构建.
client.newCall(request)
通过传入一个http request
, 返回一个Call调用
. 然后执行execute()
方法, 同步获得Response代表Http请求的响应. response.body()是ResponseBody类, 代表响应体
注意事项ÿ