Android 网络请求(二)OKHttp网络通信

学习笔记

OkHttp 是一个非常强大且流行的 HTTP 客户端库,广泛用于 Android 开发中进行网络请求。与 HttpURLConnection 相比,OkHttp 提供了更简单、更高效的 API,特别是在处理复杂的 HTTP 请求时。

如何使用 OkHttp 进行网络请求

以下是使用 OkHttp 发送一个简单的 GET 请求 和 POST 请求 的示例。

1. 在 build.gradle 中添加 OkHttp 依赖,以及网络权限

首先,你需要在项目的 build.gradle 文件中添加 OkHttp 的依赖。

java 复制代码
dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.3'
}

确保在 Gradle 同步后,能够成功引入 OkHttp 库。

添加网络权限

java 复制代码
<uses-permission android:name="android.permission.INTERNET"/>
java 复制代码
<application
        ...
        android:usesCleartextTraffic="true"
        .....
    </application>

2. 使用 OkHttp 发送 GET 请求

下面的示例展示了如何使用 OkHttp 发送一个 GET 请求并获取返回数据。

java 复制代码
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 数据)。

java 复制代码
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() 方法进行请求。

java 复制代码
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 设置请求头。

java 复制代码
Request request = new Request.Builder()
        .url("https://jsonplaceholder.typicode.com/posts")
        .header("Authorization", "Bearer your_token_here")  // 设置请求头
        .build();

6. 连接池与缓存

OkHttp 默认提供了连接池和缓存机制,可以有效地提高网络请求的效率。你可以通过自定义 OkHttpClient 来配置连接池、缓存和其他高级功能。

示例:配置缓存

java 复制代码
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。

相关推荐
千里马学框架5 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
虎头金猫5 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
美狐美颜SDK开放平台5 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc5 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
wuyk5555 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
ttyyttemo5 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077005 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
QYRdata5 天前
年均增速24.2%!机器人数据湖未来六年增长动能强劲
网络·机器人·服务发现