Android 网络编程:使用 HttpURLConnection

在 Android 开发中,网络编程是一个不可或缺的部分。HttpURLConnection 是 Android 提供的一个用于发送 HTTP 请求和接收响应的类。它是 Java 标准库的一部分,提供了一个简单的 API 来处理 HTTP 请求。尽管在 Android 中还有其他网络库(如 OkHttp 和 Retrofit),HttpURLConnection 仍然是一个重要的工具,尤其是在需要直接控制 HTTP 请求的情况下。

1. HttpURLConnection 概述

HttpURLConnection 是一个用于发送 HTTP 请求的类,支持 GET、POST、PUT、DELETE 等多种请求方式。它的优点在于:

  • 轻量级:HttpURLConnection 是 Java 标准库的一部分,不需要额外的依赖。
  • 灵活性:可以直接控制请求的各个方面,如请求头、请求体等。
  • 支持 HTTP/HTTPS:可以处理安全的 HTTPS 请求。

缺点

  • 复杂性:相较于其他网络库,HttpURLConnection 的 API 较为复杂,尤其是在处理异步请求时。
  • 错误处理:需要手动处理各种异常和错误状态,增加了代码的复杂性。

2. 基本用法

2.1 创建连接

首先,我们需要创建一个 HttpURLConnection 实例。以下是一个简单的 GET 请求示例:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpURLConnectionExample {
    public static void main(String[] args) {
        String urlString = "https://api.example.com/data"; // 替换为实际的 URL
        HttpURLConnection urlConnection = null;

        try {
            // 创建 URL 对象
            URL url = new URL(urlString);
            // 打开连接
            urlConnection = (HttpURLConnection) url.openConnection();
            // 设置请求方法
            urlConnection.setRequestMethod("GET");
            // 设置请求头
            urlConnection.setRequestProperty("Accept", "application/json");

            // 获取响应码
            int responseCode = urlConnection.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            // 处理响应
            if (responseCode == HttpURLConnection.HTTP_OK) { // 200
                BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                // 打印响应内容
                System.out.println("Response: " + response.toString());
            } else {
                System.out.println("GET request failed");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
    }
}

2.2 发送 POST 请求

发送 POST 请求的过程与 GET 请求类似,但需要设置请求方法为 POST,并且可以通过输出流发送请求体。

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpURLConnectionPostExample {
    public static void main(String[] args) {
        String urlString = "https://api.example.com/data"; // 替换为实际的 URL
        HttpURLConnection urlConnection = null;

        try {
            // 创建 URL 对象
            URL url = new URL(urlString);
            // 打开连接
            urlConnection = (HttpURLConnection) url.openConnection();
            // 设置请求方法
            urlConnection.setRequestMethod("POST");
            // 设置请求头
            urlConnection.setRequestProperty("Content-Type", "application/json");
            urlConnection.setDoOutput(true); // 允许输出流

            // 创建请求体
            String jsonInputString = "{\"name\": \"John\", \"age\": 30}";

            // 发送请求体
            try (DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream())) {
                wr.writeBytes(jsonInputString);
                wr.flush();
            }

            // 获取响应码
            int responseCode = urlConnection.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            // 处理响应
            if (responseCode == HttpURLConnection.HTTP_OK) { // 200
                BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                // 打印响应内容
                System.out.println("Response: " + response.toString());
            } else {
                System.out.println("POST request failed");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
    }
}

3. 注意事项

3.1 网络请求在主线程中执行

在 Android 中,网络请求不能在主线程中执行,否则会抛出 NetworkOnMainThreadException。因此,建议使用 AsyncTaskThreadExecutorService 来处理网络请求。

new Thread(new Runnable() {
    @Override
    public void run() {
        // 在这里执行网络请求
    }
}).start();

3.2 处理异常

在进行网络请求时,可能会遇到多种异常,如 IOExceptionMalformedURLException 等。务必在代码中进行适当的异常处理,以确保应用的稳定性。

3.3 关闭连接

在完成网络请求后,务必调用 urlConnection.disconnect() 来关闭连接,释放资源。

3.4 使用 HTTPS

在处理敏感数据时,务必使用 HTTPS 进行加密传输。HttpURLConnection 支持 HTTPS,但需要确保服务器的 SSL 证书是有效的。

4. 总结

HttpURLConnection 是一个强大且灵活的工具,适合需要直接控制 HTTP 请求的场景。尽管它的 API 较为复杂,但通过合理的封装和使用,可以有效地进行网络编程。在实际开发中,建议根据项目需求选择合适的网络库,以提高开发效率和代码可维护性。