网络请求基础
添加网络权限
在AndroidManifest.xml
中声明网络权限:

<uses-permission android:name="android.permission.INTERNET" />
网络请求方式对比
方式 |
特点 |
HttpURLConnection |
Android原生API,需手动处理连接、流操作、线程管理 |
OkHttp |
第三方库,支持连接池、缓存、拦截器,代码更简洁 |
Retrofit |
基于OkHttp的RESTful API封装,支持自动解析JSON/XML,接口定义更规范 |
使用OkHttp实现基础请求
添加依赖
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
GET请求示例
OkHttpClient client = new OkHttpClient();
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 json = response.body().string();
// 解析JSON数据
}
}
});
异步处理与UI更新
技术方案 |
适用场景 |
注意事项 |
Thread+Handler |
简单任务,需手动切换线程 |
需处理消息传递安全性 |
AsyncTask |
轻量级异步任务(已过时) |
可能导致内存泄漏 |
LiveData+ViewModel |
生命周期安全的数据更新 |
需配合架构组件使用 |
Coroutine(Kotlin) |
简洁的协程支持 |
需注意上下文切换 |
JSON数据解析
使用Gson解析
Gson gson = new Gson();
MyDataObject data = gson.fromJson(jsonString, MyDataObject.class);
复杂数据结构处理
数据类型 |
解决方案 |
嵌套对象 |
创建对应层级的Java类 |
数组 |
使用TypeToken 或List泛型 |
未知字段 |
使用JsonElement 或Map<String,Object> |
缓存策略
缓存类型 |
实现方式 |
适用场景 |
内存缓存 |
LruCache/OkHttp内置缓存 |
频繁访问的临时数据 |
磁盘缓存 |
Room数据库/SharedPreferences |
持久化存储 |
网络缓存 |
OkHttp缓存机制 |
减少重复网络请求 |
安全与异常处理
HTTPS配置
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(getSSLSocketFactory(), trustManager)
.hostnameVerifier((hostname, session) -> true) // 仅用于测试环境
.build();
异常处理清单
异常类型 |
处理方案 |
网络连接失败 |
重试机制/提示用户检查网络 |
JSON解析错误 |
捕获JsonSyntaxException |
证书验证失败 |
配置自定义TrustManager |
服务器返回错误码 |
根据状态码分类处理(如401/500) |
优化建议
- 连接复用:使用OkHttp的ConnectionPool减少重建连接开销
- 请求合并:对高频相似请求进行合并(如搜索联想词)
- 数据压缩:启用GZIP压缩减少传输数据量
- 流量控制:对大文件下载进行限速和进度监控
相关问题与解答
Q1:如何选择网络库(OkHttp/Retrofit)?
A:
- OkHttp:适合需要精细控制连接的场景(如自定义拦截器、WebSocket)
- Retrofit:适合RESTful API接口,通过注解自动生成请求,支持多种数据转换(Gson/Moshi/Xml)
- 组合使用:常用Retrofit+OkHttp组合,既享受接口定义便利又获得底层控制能力
Q2:如何处理大文件下载(如500MB视频)?
A:
- 使用DownloadManager:系统级服务,支持断点续传和通知栏显示
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setTitle("视频下载");
request.setDescription("正在下载...");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "video.mp4");
DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
manager.enqueue(request);
- 自定义下载逻辑:使用
OkHttp
的Call
配合RandomAccessFile
实现多线程下载,需处理:
- 计算文件分块范围(Range请求)
- 并发线程数控制(建议3-5个)
- 下载进度实时计算与UI更新
- 断点续传状态保存(使用
SharedPreferences
或数据库)