车载网络系统定制:ConnectivityService定制、WIFI与以太网管理、车载热点与Tethering、网络策略优化
各位好,我是老张。今天咱们聊聊车载网络系统定制。说实话,这部分内容在手机Android上已经非常成熟了,但一搬到车上,问题就全变了。我最早做车载项目时,以为直接拿手机代码改改就行,结果被车载以太网和热点策略折腾得够呛。嗯,今天就把这些坑和经验分享给大家。
8.1 ConnectivityService 定制:车载场景下的网络中枢改造
ConnectivityService 是 Android 网络框架的核心。它负责管理所有网络类型(WiFi、以太网、蜂窝等)的注册、评分、切换。在手机上,默认逻辑是“有WiFi优先用WiFi,WiFi不行切蜂窝”。但在车上,这个逻辑完全行不通。
为什么? 因为车载场景下,网络来源非常复杂:
- 车载以太网(OBD、诊断、高精地图数据流)
- 车载WiFi Station(连接停车场/家庭热点)
- 车载WiFi AP(车内乘客热点)
- 内置eSIM/4G/5G蜂窝
- USB Tethering(手机投屏共享网络)
我见过一个项目,默认的 ConnectivityService 把以太网和 WiFi 评分搞混了,导致高精地图数据走的是 WiFi 而不是有线以太网,延迟直接飙到 200ms。所以,定制 ConnectivityService 的第一步,就是重写网络评分策略。
8.1.1 网络评分策略定制
Android 的 NetworkAgent 在注册时会携带一个 score(评分),ConnectivityService 根据 score 选择默认网络。默认 WiFi 是 60,以太网是 70,蜂窝是 50。但在车上,我们需要重新定义:
// 车载网络评分建议
// 以太网(高精地图、诊断):90
// 车载WiFi Station(乘客娱乐):70
// 内置蜂窝(紧急呼叫、OTA):80
// USB Tethering(开发调试):50
// 车载热点(AP模式):40
具体怎么改?我习惯在 NetworkAgentInfo.java 的 getCurrentScore() 方法中注入车载策略。比如:
// 伪代码示例
if (networkType == TRANSPORT_ETHERNET) {
// 车载以太网优先级最高
score = 90;
// 如果是诊断口,再+10
if (isDiagnosticPort()) score += 10;
} else if (networkType == TRANSPORT_WIFI) {
// 判断是Station还是AP
if (isWifiStationMode()) {
score = 70;
} else {
// AP模式(热点)评分最低
score = 40;
}
}
8.1.2 网络切换策略优化
手机上网络切换很频繁,但车上不行。你想想看,车辆在高速行驶中,如果 WiFi 信号稍微弱一点就切到蜂窝,会导致地图数据中断、语音通话卡顿。我建议的策略是:
- 增加切换阈值:默认 score 差 5 就切换,车载建议差 15 以上才切换
- 引入“粘滞”机制:一旦连接到以太网,除非断开超过 5 秒,否则不主动切换
- 场景感知:车辆行驶中(车速 > 10km/h),禁止从以太网切到 WiFi
// 粘滞机制示例
private boolean shouldSwitchNetwork(NetworkAgentInfo current, NetworkAgentInfo candidate) {
if (current.networkType == TRANSPORT_ETHERNET && isVehicleMoving()) {
// 行驶中,以太网粘滞
return false;
}
// 正常评分比较
return candidate.getCurrentScore() - current.getCurrentScore() > SWITCH_THRESHOLD;
}
8.2 WiFi 与以太网管理:双网卡共存与优先级
车载系统通常同时存在 WiFi 和以太网。以太网用于高带宽、低延迟的数据(地图、诊断),WiFi 用于乘客娱乐。但 Android 默认只允许一个默认网络。怎么办?
我的做法是: 利用 NetworkFactory 和 NetworkCapabilities 做网络分流。让高精地图 App 绑定以太网,让浏览器、视频 App 走 WiFi。
8.2.1 网络绑定(Network Binding)
在 Android 中,App 可以通过 ConnectivityManager.bindProcessToNetwork() 绑定到特定网络。但车载场景下,我们更希望系统自动分流。我封装了一个 VehicleNetworkPolicyManager:
// 车载网络策略管理器
public class VehicleNetworkPolicyManager {
// 高精地图App包名
private static final String MAP_PACKAGE = "com.vehicle.map";
// 诊断App包名
private static final String DIAG_PACKAGE = "com.vehicle.diag";
public void onAppStarted(String packageName) {
if (MAP_PACKAGE.equals(packageName) || DIAG_PACKAGE.equals(packageName)) {
// 绑定到以太网
bindToEthernet(packageName);
} else {
// 其他App默认走WiFi或蜂窝
bindToDefaultNetwork(packageName);
}
}
}
NetworkCallback.onAvailable() 后再绑定。
8.2.2 以太网 DHCP 与静态 IP 管理
车载以太网通常有两种场景:
- 诊断口:固定 IP(如 192.168.1.100),不需要 DHCP
- 数据口:DHCP 获取 IP(连接 T-Box 或 OBD 网关)
我建议在 EthernetManager 的配置中增加一个 isDiagnosticPort 标志。如果是诊断口,直接跳过 DHCP,使用静态 IP:
// EthernetConfigStore.java 定制
if (isDiagnosticPort(iface)) {
IpConfiguration config = new IpConfiguration();
config.setIpAssignment(IpConfiguration.IpAssignment.STATIC);
StaticIpConfiguration staticConfig = new StaticIpConfiguration();
staticConfig.ipAddress = new LinkAddress("192.168.1.100", 24);
staticConfig.gateway = new InetAddress("192.168.1.1");
config.setStaticIpConfiguration(staticConfig);
return config;
}
8.3 车载热点与 Tethering:乘客娱乐与安全隔离
车载热点是刚需。乘客要刷视频、玩游戏,但热点不能影响车辆本身的网络通信。这里有两个关键点:网络隔离和带宽限制。
8.3.1 热点与车载网络隔离
默认的 Android Tethering 会把热点流量直接路由到蜂窝或 WiFi。但在车上,热点流量应该走独立的网络栈,不能和以太网(高精地图)混在一起。我采用 VLAN 或 iptables 标记 的方式隔离:
# 创建独立的网络命名空间
ip netns add hotspot_ns
# 将热点接口移入该命名空间
ip link set wlan1 netns hotspot_ns
# 在命名空间中配置独立的路由和 NAT
ip netns exec hotspot_ns iptables -t nat -A POSTROUTING -o rmnet0 -j MASQUERADE
这样,热点流量和车载以太网流量完全隔离。即使乘客把带宽占满,也不会影响地图导航。
Tethering.java 中排除以太网接口。
8.3.2 带宽限制与 QoS
乘客看视频可以,但不能影响驾驶安全相关的网络。我建议在热点的 iptables 中做带宽限制:
# 限制热点总带宽为 20Mbps
iptables -A FORWARD -i wlan1 -o rmnet0 -m limit --limit 20mbit -j ACCEPT
iptables -A FORWARD -i wlan1 -o rmnet0 -j DROP
同时,为高优先级流量(如地图更新、OTA)预留带宽:
# 为地图App预留 10Mbps
iptables -t mangle -A OUTPUT -p tcp --dport 443 -m owner --uid-owner map_app_uid -j CLASSIFY --set-class 1:10
8.4 网络策略优化:省电、安全与稳定性
车载网络策略和手机完全不同。手机可以随时开关 WiFi、切换网络,但车不行。车辆启动后,网络必须快速就绪,而且不能频繁切换。
8.4.1 网络唤醒与快速连接
车辆从休眠到唤醒,网络模块需要快速上线。我建议:
- 以太网:使用 WoL(Wake-on-LAN)功能,车辆解锁即唤醒以太网 PHY
- WiFi:保存上次连接的 BSSID,跳过扫描阶段,直接尝试连接
- 蜂窝:保持 RRC 连接(不进入 IDLE 态),减少 RRC 重建时间
// WiFi 快速连接示例
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 跳过扫描,直接连接已知网络
wifiManager.connect(wifiManager.getConfiguredNetworks().get(0), null);
8.4.2 省电策略:按需关闭网络
车辆熄火后,网络模块不能一直开着,否则电瓶会亏电。我建议的策略是:
| 车辆状态 | 以太网 | WiFi | 蜂窝 |
|---|---|---|---|
| 行驶中 | 开启 | 开启(乘客) | 开启(OTA) |
| 停车(ACC ON) | 开启 | 开启 | 开启 |
| 停车(ACC OFF) | 关闭 | 关闭 | 低功耗模式(仅接收紧急消息) |
| 休眠 | 关闭 | 关闭 | 关闭(RTC 定时唤醒检查 OTA) |
这个策略我是在 VehicleNetworkPolicyService 中实现的,监听车辆电源状态广播,动态开关网络接口。
8.4.3 安全策略:防止网络劫持
车载网络的安全性不容忽视。我见过一个案例,黑客通过车载 WiFi 热点入侵了以太网,篡改了地图数据。解决方案是:
- 网络隔离:热点和车载网络使用不同的 VLAN
- 防火墙:在以太网接口上只允许特定端口(如 443、1234)
- 证书校验:所有 OTA 和地图更新必须校验服务器证书
# 以太网防火墙规则示例
iptables -A INPUT -i eth0 -p tcp --dport 22 -j DROP # 禁止SSH
iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT # 只允许HTTPS
iptables -A INPUT -i eth0 -j DROP # 其他全部丢弃
知识体系总览
下面这张图是我梳理的车载网络系统定制核心逻辑,大家可以对照着看:
好了,以上就是车载网络系统定制的核心内容。从 ConnectivityService 的评分策略,到 WiFi/以太网的双网卡管理,再到热点隔离和网络策略优化,每一步都有不少细节。我个人觉得,最关键的是要理解车载场景的特殊性——网络不是给一个人用的,而是给车和乘客同时用的,优先级和隔离必须做好。
如果你在实际项目中遇到网络切换异常、热点影响车载通信等问题,可以回头看看今天讲的这几个点。嗯,今天就到这里。