OkHttp是处理网络请求的开源项目,是目前Android使用最广泛的网络框架。 github地址:https://github.com/square/okhttp 需引入依赖
implementation("com.squareup.okhttp3:okhttp:4.9.1")
一、同步GET请求
- 完成同步网络请求需要在子线程中完成
- 声明Request对象:传入url地址,调用build()返回对象
- 声明Call对象:调用OkhttpClient的newCall方法,传入request
- 声明Response对象:调用call.execute()将请求封装
- 调用Response对象的body()方法,可以得到服务器返回的数据
new Thread(){
@Override
public void run() {
Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
Log.d("TAG",response.body().string());
}
catch (IOException e){
e.printStackTrace();
}
}
}.start();
二、异步GET请求
- 声明Request对象:传入url地址,调用build()返回对象
- 声明Call对象:调用OkhttpClient的newCall方法,传入request
- 声明Response对象:调用call.enqueue(new Callback(){})进行异步请求
- 实现Callback接口中的方法:onFailure(),onResponse()
- 在onResponse()方法中调用response的isSuccessful()方法判断响应成功,如果成功调用response.body()获取服务器返回的主体
异步请求相比于同步请求,不会阻塞,且不需要自己手动开辟一个子线程。
Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
if (response.isSuccessful()){
Log.d("TAG",response.body().string());
}
}
});
三、同步POST请求
- 申请一个子线程,在子线程中进行请求
- 声明一个FormBody对象,使用add()方法加数据,调用build()完成创建
- 声明Request对象,在调用build之前调用post()方法传入参数FormBody对象。
- 声明Call对象:调用OkhttpClient的newCall方法,传入request
- 声明Response对象:调用call.execute()将请求封装
- 调用Response对象的body()方法,可以得到服务器返回的数据
new Thread(){
@Override
public void run() {
FormBody formBody = new FormBody.Builder()
.add("a","1")
.add("b","2")
.build();
Request request = new Request.Builder().url("https://www.httpbin.org/post").post(formBody).build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
Log.d("TAG",response.body().string());
}
catch (IOException e){
e.printStackTrace();
}
}
}.start();
四、异步POST请求
- 声明一个FormBody对象,使用add()方法加数据,调用build()完成创建
- 声明Request对象,在调用build之前调用post()方法传入参数FormBody对象。
- 声明Call对象:调用OkhttpClient的newCall方法,传入request
- 声明Response对象:调用call.enqueue(new Callback(){})进行异步请求
- 在onResponse()方法中调用response的isSuccessful()方法判断响应成功,如果成功调用response.body()获取服务器返回的主体
FormBody formBody = new FormBody.Builder()
.add("a","1")
.add("b","2")
.build();
Request request = new Request.Builder().url("https://www.httpbin.org/post").post(formBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
if (response.isSuccessful()){
Log.d("YCF",response.body().string());
}
}
});
五、POST请求的数据格式
Http协议规定POST提交的数据必须放在请求体中,但协议并没有规定数据必须使用什么编码方式。编码参考网址: https://www.runoob.com/http/http-content-type.html 常用的数据编码方式有:
- application/x-www-form-urlencoded 数据被编码成键值对,默认类型。不适合提交文件
- application/octet-stream 提交二进制数据,如果用于文件上传,只能上传一个文件
- multipart/form-data 数据被编码成一条消息,一般用于文件上传,而且支持多文件
- application/json 提交json数据
提交文件的例子:
new Thread(){
@Override
public void run() {
File httptest = new File("D:\\desktop");
MultipartBody body = new MultipartBody.Builder()
.addFormDataPart("httptest", httptest.getName(), RequestBody.create(httptest, MediaType.parse("text/plain")))
.build();
Request request = new Request.Builder().url("https://www.httpbin.org/post").post(body).build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
Log.d("TAG",response.body().string());
}
catch (IOException e){
e.printStackTrace();
}
}
}.start();
六、Okhttp的自定义配置
自定义配置OkHttp需要使用Builder构建OkHttpCilent对象。 (1)拦截器配置 如果是使用添加了拦截器的OKHttpClient进行请求,则在请求的过程中,会执行拦截器中定义的方法。
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new XXX).build();
或
OkHttpClient okHttpClient = new OkHttpClient.Builder().addNetworkInterceptor(new XXX).build();
- 创建一个拦截器类,在其中调用上述方法在参数列表中new一个Interceptor,重写intercept()方法
- 通过回调参数chain调用request()方法得到Request对象
- 如果直接返回chain.proceed(chain.request())相当于过了一遍拦截器,但是没有做任何操作,因此应该在返回这个response对象之前完成处理
- 在得到response对象的前后进行的处理分别叫做前置处理和后置处理
- 在前置处理中对request对象做出改变,然后传给chain.proceed()方法得到response对象
(2)缓存和Cookie OkHttp按照协议实现了缓存的处理,如果后续请求与前面的请求类似,符合缓存规则,则可以减少与服务器的网络通信,直接从本地文件缓存中读取响应返回给请求者。默认情况下,OkHttp缓存是关闭状态需要手动开启 OkHttpClient okHttpClient = new OkHttpClient.Builder().cache(new Cache(new File("/path/cache"),1024)).build(); 第一个参数是缓存路径,第二个是缓存的最大空间
|