大量网络交互的项目,页面加载慢、请求失败率高等问题频繁出现,趁机系统整理了一下 Android 网络层优化的一些思路,记录如下 —— 不一定全对,但是目前阶段我的理解,如有补充欢迎留言交流!


一、常见网络问题梳理

在实际项目中,网络层容易遇到这些问题:

  • 请求响应慢、首屏加载时间长
  • 数据重复请求、过度消耗流量
  • 网络失败率高,用户体验差
  • 请求卡顿或 UI 卡顿(主线程阻塞)
  • 电量消耗大(后台频繁请求)

二、基础优化方案

1. 使用高效的网络框架

目前推荐:

  • OkHttp:底层 HTTP 客户端,支持连接复用、自动压缩、缓存等
  • Retrofit:基于 OkHttp 的封装,支持注解式请求、响应转换器
  • Volley / Ktor(Kotlin)也可选,根据项目栈定

优化建议

  • 复用 OkHttpClient 实例,避免频繁创建连接池
  • 开启 HTTP 缓存:设置 Cache,减少重复请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int cacheSize = 10 * 1024 * 1024; // 10MB
Cache cache = new Cache(new File(context.getCacheDir(), "http_cache"), cacheSize);
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
````

---

### 2. DNS 优化与预解析

DNS 解析是首次请求的重要延迟来源之一。

**建议**:

* 使用 OkHttp 的 `Dns.OVER_HTTPS` 或自定义 DNS(例如 114DNS)
* 对频繁访问的域名做 DNS 预解析(App 启动时调用)

---

### 3. 开启 Gzip 压缩传输

默认 OkHttp 是自动支持的,但需要服务器端返回 `Content-Encoding: gzip`。

作用:降低流量、提升传输速度(尤其是 JSON 数据)

---

### 4. 使用连接池与超时配置

避免频繁握手、重复建链:

```java
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();

三、高阶优化手段

1. 异常与超时重试机制

可使用:

  • RetryAndFollowUpInterceptor(OkHttp 自带)
  • 自定义重试机制(例如只对某些 5xx 状态重试)

注意:避免对所有请求无限制重试,建议加入最大重试次数和指数退避。


2. 请求合并 & 去抖动

针对:

  • 多个组件同时请求同一接口
  • 连续触发请求(如文本搜索)

思路

  • 使用 RxJava/Flow + debounce 操作符处理请求频率
  • 维护请求队列,根据唯一 key 去重

3. 网络请求分发调度

  • 分场景区分优先级(主线程渲染请求 vs 后台上传)
  • 使用自定义线程池或 CoroutineDispatcher 控制调度

4. 使用 CDN 缓解服务压力

对于图片、视频等静态资源,一定要启用 CDN,避免拉取慢、服务端压力大。

可配合 OkHttp 的 Interceptor 添加缓存策略(如控制 Cache-Control)。


四、移动端专属优化点

1. 网络监听与降级策略

当网络不可用或不稳定时,进行适当降级处理:

1
2
3
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
boolean isConnected = networkInfo != null && networkInfo.isConnected();

建议结合:

  • Jetpack 的 NetworkCallback 进行实时监听
  • 弹出友好提示 / 使用本地缓存兜底

2. 后台网络调度限制(节电)

  • 使用 WorkManager 统一后台请求调度
  • 避免过于频繁的轮询或心跳
  • 设置约束条件(如联网 + 充电时执行)

3. 图片加载优化

  • 使用 Glide/Picasso/Fresco 控制缓存策略
  • 尽量使用 WebP 格式减小体积
  • 尽量指定尺寸加载,避免原图加载浪费资源
1
2
3
4
5
Glide.with(context)
.load(url)
.override(300, 300)
.centerCrop()
.into(imageView);

五、Debug 与监控建议

  • ✅ 使用 StethoChuckOkHttp Logging 等工具查看网络请求
  • ✅ 引入 Crashlytics 或自定义统计失败接口、耗时
  • ✅ 建议接入后端链路追踪系统(如 Zipkin、Jaeger)配合调试