上一篇
安卓开发获取网页数据
- 行业动态
- 2025-04-21
- 4
安卓开发获取网页数据的方法与实践
网络权限配置
在Android应用中进行网络请求前,需在AndroidManifest.xml
中声明网络权限:
<uses-permission android:name="android.permission.INTERNET" />
常用网络请求方式对比
方法 | 优点 | 缺点 |
---|---|---|
HttpURLConnection |
系统原生支持,无需额外依赖 | 代码繁琐,API不友好 |
OkHttp |
轻量级,链式调用,支持缓存 | 需手动管理线程 |
Retrofit |
强大的注解支持,适配RxJava | 学习成本较高,依赖库较大 |
HttpURLConnection
实现示例
// 同步请求(需在子线程执行) public String getWebData(String url) throws IOException { URL requestUrl = new URL(url); HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); // 设置超时时间 connection.connect(); int responseCode = connection.getResponseCode(); if (responseCode == 200) { InputStream inputStream = connection.getInputStream(); return streamToString(inputStream); // 需实现流转换方法 } else { throw new IOException("HTTP error code: " + responseCode); } }
OkHttp
实现示例
// 添加依赖:implementation 'com.squareup.okhttp3:okhttp:4.10.0' OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .build(); Request request = new Request.Builder() .url("https://api.example.com/data") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 处理失败 } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String data = response.body().string(); // 处理成功数据 } } });
Retrofit
实现示例
// 添加依赖:implementation 'com.squareup.retrofit2:retrofit:2.9.0' interface ApiService { @GET("path/to/resource") Call<ResponseBody> getData(); } Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); ApiService apiService = retrofit.create(ApiService.class); Call<ResponseBody> call = apiService.getData(); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (response.isSuccessful()) { // 解析响应体 } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // 处理失败 } });
注意事项
- 主线程限制:Android禁止在主线程进行网络操作,需使用子线程或异步框架(如
AsyncTask
、RxJava
、Coroutine
) - HTTPS证书验证:生产环境需正确处理SSL证书,测试环境可临时禁用验证(不推荐)
- 错误处理:需处理网络异常、超时、响应码非200等情况
- 数据解析:根据返回类型选择解析方式(JSON/XML/Protobuf等)
相关问题与解答
Q1:如何处理HTTPS证书主机名验证失败?
A:可通过配置OkHttp
或Retrofit
的SSLSocketFactory
实现自定义验证逻辑,示例:
// 创建信任所有证书的TrustManager(仅限测试环境) TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; // 初始化SSL上下文 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); // 配置OkHttpClient OkHttpClient client = new OkHttpClient.Builder() .sslSocketFactory(socketFactory, (X509TrustManager)trustAllCerts[0]) .hostnameVerifier((hostname, session) -> true) // 禁用主机名验证 .build();
注意:此方法存在安全风险,生产环境应使用正规证书。
Q2:如何在Retrofit中添加统一的请求头?
A:通过OkHttpClient
拦截器或Interceptor
实现:
// 创建带拦截器的OkHttpClient OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(chain -> { Request original = chain.request(); Request requestWithHeader = original.newBuilder() .header("Authorization", "Bearer token") .header("Content-Type", "application/json") .build(); return chain.proceed(requestWithHeader); }) .build(); // 将客户端传递给Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .client(client) .build();