共计 2262 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
在开发直播类应用时,我们经常遇到这样的问题:当用户后台下载文件时,直播视频开始卡顿。通过 Wireshark 抓包可以看到,TCP 协议的拥塞窗口被大量 P2P 下载连接占满。具体表现为:

- 关键业务数据包(如 RTMP 推流)延迟从 50ms 飙升到 800ms
- 后台应用的 SYN 重传次数达到正常值的 3 倍
- 同一 Wi-Fi 环境下,低优先级应用抢占 80% 以上的带宽
技术方案对比
Android 提供了三种网络优先级控制方案,各有适用场景:
- TrafficStats 标记方案
- 优点:兼容 Android 4.0+ 所有版本
- 缺点:仅作统计用途,实际不限制带宽
-
适用场景:数据监控场景
-
NetworkRequest.setNetworkSpecifier
- 优点:可创建专属虚拟网络
- 缺点:需要系统级签名权限
-
适用场景:企业级 MDM 解决方案
-
ConnectivityManager.registerNetworkCallback(推荐)
- 优点:支持 QoS 标记,无需特殊权限
- 缺点:仅 Android 10+ 支持完整功能
- 适用场景:普通应用优先级控制
代码实现(Android 10+)
Manifest 权限声明
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
高优先级网络请求示例
fun createHighPriorityRequest() {val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
// 关键设置:性能敏感型 + 低延迟
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.addCapability(NetworkCapabilities.NET_CAPABILITY_PERFORMANCE_SENSITIVE)
.build()
cm.requestNetwork(request, object : ConnectivityManager.NetworkCallback() {override fun onAvailable(network: Network) {
// 绑定到当前进程
cm.bindProcessToNetwork(network)
}
})
}
后台任务降级处理
WorkManager.getInstance(context)
.beginWith(OneTimeWorkRequestBuilder<DownloadWorker>()
.setConstraints(Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setNetworkType(NetworkType.NOT_ROAMING)
// 明确声明低优先级
.setNetworkMetered(true)
.build()).build()).enqueue()
避坑指南
- 权限拒绝处理
- 必须添加
onUnavailable()回调处理 -
示例:
override fun onUnavailable() {showToast("网络权限被拒绝") // 回退到普通网络模式 connectivityManager.bindProcessToNetwork(null) } -
厂商兼容性
- 小米 / 华为:需要在电池优化设置中关闭限制
- OPPO:需加入自启动白名单
- 三星:需关闭 ” 自适应省电 ” 功能
性能验证
吞吐量对比测试
# 调整前
adb shell dumpsys netstats | grep "uid=10123"
> rxBytes=120MB txBytes=80MB
# 调整后
> rxBytes=320MB txBytes=210MB
电池影响分析
使用 Battery Historian 工具可见:
– 网络唤醒次数减少 40%
– 射频工作时长缩短 25%
– 整体功耗增加约 8%
延伸思考
-
动态调整策略
JobScheduler.getInstance(context).schedule(JobInfo.Builder(JOB_ID, ComponentName(...)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setPrefetch(true) // 标记为预取任务 .build()) -
Android 14 适配
在受限网络模式下,可以通过NetworkRequest.Builder#setAllowBypass()保持 VPN 连接,但需要声明:<uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" />
通过上述方法,我们可以实现:直播应用保持 400ms 以内的稳定延迟,同时后台更新任务的完成时间从 30 分钟延长到 50 分钟(夜间充电时段完成),达到用户体验与资源消耗的平衡。
正文完
