Android 网络请求(二)OKHttp网络通信
学习笔记
OkHttp
是一个非常强大且流行的 HTTP 客户端库,广泛用于 Android 开发中进行网络请求。与 HttpURLConnection
相比,OkHttp
提供了更简单、更高效的 API,特别是在处理复杂的 HTTP 请求时。
如何使用 OkHttp 进行网络请求
以下是使用 OkHttp 发送一个简单的 GET 请求 和 POST 请求 的示例。
1. 在 build.gradle
中添加 OkHttp 依赖,以及网络权限
首先,你需要在项目的 build.gradle
文件中添加 OkHttp 的依赖。
dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
}
确保在 Gradle 同步后,能够成功引入 OkHttp 库。
添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
<application
...
android:usesCleartextTraffic="true"
.....
</application>
2. 使用 OkHttp 发送 GET 请求
下面的示例展示了如何使用 OkHttp 发送一个 GET 请求并获取返回数据。
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpExample {
public String getDataFromServer() {
OkHttpClient client = new OkHttpClient(); // 创建 OkHttpClient 实例
// 创建一个 GET 请求对象
Request request = new Request.Builder()
.url("https://jsonplaceholder.typicode.com/posts") // 设置目标 URL
.build();
// 用于保存响应内容
String result = "";
try {
// 执行请求,返回一个 Response 对象
Response response = client.newCall(request).execute();
// 检查响应是否成功
if (response.isSuccessful()) {
// 获取响应的内容(如 JSON)
result = response.body().string(); // 读取响应体的内容
} else {
result = "Request failed with code: " + response.code(); // 请求失败
}
} catch (IOException e) {
e.printStackTrace();
result = "Error: " + e.getMessage(); // 捕获异常并返回错误信息
}
return result; // 返回请求结果
}
}
代码解释:
-
OkHttpClient client = new OkHttpClient();
:创建一个OkHttpClient
实例,这个实例用于执行网络请求。 -
Request request = new Request.Builder().url(...).build();
:构建请求对象,通过Request.Builder
设置 URL 和其他请求参数。 -
Response response = client.newCall(request).execute();
:使用newCall(request).execute()
执行请求并获取响应。 -
response.body().string()
:获取响应体的内容,通常是 JSON 格式的字符串。 -
response.code()
:获取响应的 HTTP 状态码,用于判断请求是否成功。
3. 使用 OkHttp 发送 POST 请求
下面是如何使用 OkHttp 发送 POST 请求,并传递一些请求体(例如 JSON 数据)。
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class OkHttpExample {
public String postDataToServer() {
OkHttpClient client = new OkHttpClient(); // 创建 OkHttpClient 实例
// 创建请求的 JSON 数据体
String json = "{\"title\":\"foo\", \"body\":\"bar\", \"userId\":1}";
// 设置请求体类型为 JSON
MediaType JSON = MediaType.get("application/json; charset=utf-8");
// 创建一个 POST 请求对象,包含请求体
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url("https://jsonplaceholder.typicode.com/posts") // 设置目标 URL
.post(body) // 设置 POST 请求体
.build();
// 用于保存响应内容
String result = "";
try {
// 执行请求并获取响应
Response response = client.newCall(request).execute();
// 检查响应是否成功
if (response.isSuccessful()) {
result = response.body().string(); // 获取响应体的内容
} else {
result = "Request failed with code: " + response.code(); // 请求失败
}
} catch (IOException e) {
e.printStackTrace();
result = "Error: " + e.getMessage(); // 捕获异常并返回错误信息
}
return result; // 返回请求结果
}
}
代码解释:
-
String json = "{\"title\":\"foo\", \"body\":\"bar\", \"userId\":1}";
:这里创建了一个 JSON 字符串,表示要发送的请求体。 -
MediaType JSON = MediaType.get("application/json; charset=utf-8");
:指定请求体的类型为application/json
,告诉服务器发送的是 JSON 格式的数据。 -
RequestBody body = RequestBody.create(json, JSON);
:将 JSON 字符串转换为RequestBody
对象,这个对象会作为请求体发送给服务器。 -
request.post(body)
:将请求体添加到请求对象中,指定该请求是一个 POST 请求。
4. 异步请求
在 Android 中,网络请求需要在后台线程中进行,避免阻塞主线程。如果你不希望使用同步请求,可以使用 OkHttp 的 异步请求,通过 enqueue()
方法进行请求。
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpExample {
public void getDataFromServerAsync() {
OkHttpClient client = new OkHttpClient(); // 创建 OkHttpClient 实例
// 创建 GET 请求对象
Request request = new Request.Builder()
.url("https://jsonplaceholder.typicode.com/posts")
.build();
// 异步请求
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 请求失败时的处理
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
// 请求成功时,处理响应数据
String result = response.body().string();
// 在此处处理返回的结果,更新 UI(需要在主线程中进行)
} else {
// 请求失败时,处理失败的情况
System.out.println("Request failed with code: " + response.code());
}
}
});
}
}
异步请求的关键点:
-
client.newCall(request).enqueue(new Callback() {...})
:异步请求的方法。 -
onFailure()
:请求失败时的回调方法。 -
onResponse()
:请求成功时的回调方法,响应数据会传递到此。
注意: 由于
onResponse()
方法是在后台线程中执行的,任何 UI 更新操作需要通过runOnUiThread()
或其他线程间通信机制来确保在主线程中执行。
5. 处理请求头
如果你需要在请求中设置请求头(例如设置身份验证的 Token),可以通过 Request.Builder
设置请求头。
Request request = new Request.Builder()
.url("https://jsonplaceholder.typicode.com/posts")
.header("Authorization", "Bearer your_token_here") // 设置请求头
.build();
6. 连接池与缓存
OkHttp 默认提供了连接池和缓存机制,可以有效地提高网络请求的效率。你可以通过自定义 OkHttpClient
来配置连接池、缓存和其他高级功能。
示例:配置缓存
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import java.io.File;
File cacheDir = new File(getCacheDir(), "http_cache");
Cache cache = new Cache(cacheDir, 10 * 1024 * 1024); // 10MB 的缓存
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
总结
-
同步请求:使用
client.newCall(request).execute()
,可以直接获取响应内容,但它会阻塞当前线程,不适合在 UI 线程中执行。 -
异步请求:使用
client.newCall(request).enqueue(callback)
,通过回调来处理响应数据,适合在 UI 线程中执行,避免阻塞 UI。 -
POST 请求:可以通过
RequestBody
创建请求体,并通过request.post(body)
来发送。 -
请求头:可以通过
Request.Builder().header()
设置自定义请求头。
OkHttp
是一个功能强大且易于使用的 HTTP 客户端,适用于大多数 Android 项目的网络请求。对于复杂的请求场景,推荐使用 OkHttp
。