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。

相关推荐
发光小北1 小时前
EtherNet/IP 转 ModbusTCP 网关现场应用中会遇到什么问题?
服务器·网络·tcp/ip
海宇大数据1 小时前
零信任架构实战:基于海宇全能小微企业报告构建自动化持牌网络小贷小微商户极速助业贷秒级全维风险决策网关
网络·人工智能·架构·自动化
tongyiixiaohuang2 小时前
供应商主数据同步实战:从易快报到金蝶云星空的单一策略落地
java·网络·数据库
一只鹿鹿鹿3 小时前
智算算力、AI-芯片与产品解析(PPT文件)
大数据·运维·网络·人工智能·物联网·1024程序员节
开源必胜3 小时前
Socket、异步非阻塞 I/O 与 NGINX、Netty 模型
网络·tcp/ip·nginx
沫璃染墨3 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
拥小抱3 小时前
Compose 知识点
android
文章永久免费只为良心3 小时前
Web应用安全与防护_第三章_日志文件包含_从一道 CTFshow 题目讲透「日志投毒型 LFI → RCE」:原理、时序陷阱与全变种攻防手册
android·网络安全·渗透测试·漏洞危害·漏洞描述·日志投毒·红队指南
AIsoft_86894 小时前
学术讲座录音如何整理?录音APP可行吗
android·iphone
蓝祁子yoky4 小时前
Qt学习日记 Day13:网络编程(一)-TCP基础与Socket实战
网络·qt·学习