Bootstrap

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();

总结

  1. 同步请求:使用 client.newCall(request).execute(),可以直接获取响应内容,但它会阻塞当前线程,不适合在 UI 线程中执行。

  2. 异步请求:使用 client.newCall(request).enqueue(callback),通过回调来处理响应数据,适合在 UI 线程中执行,避免阻塞 UI。

  3. POST 请求:可以通过 RequestBody 创建请求体,并通过 request.post(body) 来发送。

  4. 请求头:可以通过 Request.Builder().header() 设置自定义请求头。

OkHttp 是一个功能强大且易于使用的 HTTP 客户端,适用于大多数 Android 项目的网络请求。对于复杂的请求场景,推荐使用 OkHttp

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;