介绍
OkHttp是一个网络框架库,在之前已经介绍过另一个网络框架库Volley
,这次我们再了解一下OkHttp
本文只是介绍基本的使用,如果需要更加详细的介绍,可以参考了以下这篇文章:
使用
按照惯例,先添加依赖:
implementation 'com.squareup.okhttp3:okhttp:4.2.2'
网络请求主要为Get
请求和Post
请求,其中Get
请求又可分为同步和异步
先介绍一下Get
请求的同步方式
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.baidu.com")
.get() // 默认为get方式,可不写
.build();
Call call = client.newCall(request);
try {
Response response = call.execute();
if (response.isSuccessful()) {
String string = response.body().string();
// 可进行相关UI更新操作,但必须是在主线程中
Log.d(TAG, String.format("response:%s", string));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
再来看一下Get
请求的异步方式:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.baidu.com")
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()) {
String string = response.body().string();
// 可进行相关UI更新操作,但必须是在主线程中
Log.d(TAG, String.format("response:%s", string));
}
}
});
可以看到两种方式基本相同,
同步方式需要手动创建子线程,使用call.execute()
来获得Response
对象;
异步方式不需要手动创建子线程,使用call.enqueue(callback)
,在回调中返回Response
对象
这里贴出之前的Volly的Get
请求代码:
RequestQueue requestQueue = Volley.newRequestQueue(this);
String url = "https://www.baidu.com";
StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// 请求成功
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// 请求失败
}
});
requestQueue.add(stringRequest);
接下来看一下Post
请求的实现方式:
OkHttpClient client = new OkHttpClient();
FormBody formBody = new FormBody.Builder()
.add("name", "Tom")
.build();
Request request = new Request.Builder()
.url("https://www.baidu.com/")
.post(formBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.d(TAG, String.format("error:%s", e.getMessage()));
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()) {
String string = response.body().string();
// 可进行相关UI更新操作,但必须是在主线程中
Log.d(TAG, String.format("response:%s", string));
}
}
});
可以看到多了一个post(requetBody)
方法,需要传入一个RequestBody
参数,RequestBody
是有一个抽象类,有两个子类FormBody
和MultipartBody
,前者用于传输表单的数据,后者在传输表单数据的同时,还能传输文件
当然我们还可以直接创建RequestBody
对象
// 传输文件
MediaType jsonType = MediaType.get("application/octet-stream");
File file = new File("typora.txt");
RequestBody requestBody = RequestBody.create(file, jsonType);
// 传输Json
MediaType jsonType = MediaType.parse("application/json; charset=utf-8");
String jsonStr = "{\"name\":\"Tom\"}";
RequestBody requestBody = RequestBody.create(jsonStr, jsonType);
作为一个网络框架,自然是可以设置超时时间的:
OkHttpClient client = new OkHttpClient.Builder()
.callTimeout(6000, TimeUnit.MILLISECONDS)
.connectTimeout(6000, TimeUnit.MILLISECONDS)
.readTimeout(6000, TimeUnit.MILLISECONDS)
.writeTimeout(6000, TimeUnit.MILLISECONDS)
.build();
还有就是设置请求头Header:
Request request = new Request.Builder()
.url("https://www.baidu.com/")
.post(formBody)
.header("Charset", "UTF-8")
.headers(
new Headers.Builder()
.add("Charset", "UTF-8").build()
)
.addHeader("Charset", "UTF-8")
.removeHeader("Charset")
.build();
可以看到有四个关于Header
的操作方法,根据方法名也比较好理解,add/remove
就是添加/移除Header
,header/headers
就是把请求中的Header
信息替换掉
补充
OkHttp中还有一个拦截器,先看下面的示例代码:
public class LoginInterceptor implements Interceptor {
private final String TAG = "LoginInterceptor:OkHttp";
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request request = chain.request();
Log.d(TAG, String.format("request: \n1.%s\n2.%s\n3.%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
Log.d(TAG, String.format("response: \n1.%s\n2.%s",
response.request().url(), response.headers()));
return response;
}
}
实现拦截器必须要实现Interceptor
,并实现intercept(chain)
方法,可以看到需要返回Response
对象,所以还不需要执行Response response = chain.proceed(request);
并返回Response
对象
拦截器分为应用拦截器和网络拦截器,这里借用参考文章中的图:
OkHttpClient client = new OkHttpClient.Builder()
//.addInterceptor(new LoginInterceptor()) // 添加应用拦截器
.addNetworkInterceptor(new LoginInterceptor()) // 添加网络拦截器
.build();
关于OkHttp的基本使用就这些了