网络性能优化
问题
Android 应用的网络性能如何优化?
答案
网络优化策略
| 策略 | 说明 |
|---|---|
| 减少请求次数 | 合并接口、GraphQL |
| 减小数据量 | Gzip、Protocol Buffers |
| 缓存 | OkHttp Cache、本地数据库 |
| 连接复用 | HTTP/2、Keep-Alive |
| 弱网适配 | 超时重试、降级策略 |
OkHttp 优化配置
val client = OkHttpClient.Builder()
// 连接池复用
.connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
// 缓存
.cache(Cache(cacheDir, 50L * 1024 * 1024))
// 超时
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
// Gzip 自动处理(OkHttp 默认添加 Accept-Encoding: gzip)
.build()
弱网适配
// 监听网络状态
val connectivityManager = getSystemService(ConnectivityManager::class.java)
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(
network: Network,
capabilities: NetworkCapabilities
) {
val downSpeed = capabilities.linkDownstreamBandwidthKbps
when {
downSpeed < 150 -> loadLowQualityImages() // 2G
downSpeed < 550 -> loadMediumQualityImages() // 3G
else -> loadHighQualityImages() // 4G/WiFi
}
}
}
connectivityManager.registerDefaultNetworkCallback(networkCallback)
Protobuf vs JSON
| 特性 | JSON | Protobuf |
|---|---|---|
| 数据大小 | 较大(文本格式) | 小 3-10 倍 |
| 解析速度 | 慢 | 快 5-100 倍 |
| 可读性 | ✅ 可读 | ❌ 二进制 |
| Schema | 无强类型 | 有 .proto 定义 |
常见面试问题
Q1: 如何减少 API 响应大小?
答案:
- Gzip 压缩:OkHttp 默认支持
- Protobuf:替代 JSON
- 按需字段:GraphQL 或 API 支持
fields参数 - 增量更新:只返回变更数据
- 分页:大列表分页加载
Q2: 如何实现离线优先的网络策略?
答案:
// 拦截器实现:有缓存先用缓存
class OfflineInterceptor(private val context: Context) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
if (!isNetworkAvailable(context)) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build()
}
return chain.proceed(request)
}
}
结合 Room 数据库做本地持久化,网络请求成功后更新数据库,UI 监听数据库变化。