1. 核心架构层次
┌─────────────────────────────────────────────────────────────────┐
│ 应用层 (Application) │
│ - ConnectivityManager.requestNetwork() │
│ - NetworkRequest (capability: INTERNET, MMS 等) │
└────────────────────────┬────────────────────────────────────────┘
│ NetworkRequest
▼
┌─────────────────────────────────────────────────────────────────┐
│ ConnectivityService (Framework) │
│ - 网络评分和请求匹配 │
│ - 选择最优网络提供者 │
└────────────────────────┬────────────────────────────────────────┘
│ 选定 Telephony
▼
┌─────────────────────────────────────────────────────────────────┐
│ TelephonyNetworkFactory (NetworkFactory) │
│ - 处理 Telephony 的网络请求 │
│ - 与 DataNetworkController 通信 │
└────────────────────────┬────────────────────────────────────────┘
│ addNetworkRequest()
▼
┌─────────────────────────────────────────────────────────────────┐
│ DataNetworkController (Per-SIM) │
│ - 核心数据连接管理器 │
│ - 选择合适的 APN/DataProfile │
│ - 管理 DataNetwork 实例 │
└────────────────────────┬────────────────────────────────────────┘
│ setupDataCall()
▼
┌─────────────────────────────────────────────────────────────────┐
│ DataServiceManager (Modem Interface) │
│ - 通过 AIDL 与 DataService 通信 │
│ - 向 Modem 发送 PDP 建立命令 │
└────────────────────────┬────────────────────────────────────────┘
│ IDataService.setupDataCall()
▼
┌─────────────────────────────────────────────────────────────────┐
│ CellularDataService (RIL 实现) │
│ - DataService 的具体实现 │
│ - 调用 RIL 命令 │
└────────────────────────┬────────────────────────────────────────┘
│ RIL.setupDataCall()
▼
┌─────────────────────────────────────────────────────────────────┐
│ RadioDataProxy (HAL Interface) │
│ - 发送 RIL 命令到 Modem HAL │
│ - 1.4/1.5/1.6 版本支持 │
└────────────────────────┬────────────────────────────────────────┘
│ IRadioData.setupDataCall_1_6()
▼
┌─────────────────────────────────────────────────────────────────┐
│ Modem 硬件 │
│ - PDP 上下文激活 │
│ - 链路层连接 │
└─────────────────────────────────────────────────────────────────┘
2. 蜂窝数据连接的完整生命周期
2.1 状态机模型
DataNetwork 的 5 个主要状态:
┌──────────────────────────────────────────────────────────────┐
│ │
│ ┌─────────┐ ┌──────────┐ │
│ │Connecting├─────►Connected ├─────┐ │
│ └────┬────┘ └────┬─────┘ │ │
│ │ │ │ │
│ ┌────▼─────────┐ │ ┌────▼──────────┐ │
│ │Disconnected ◄┼──────┼──────► Disconnecting │ │
│ └──────────────┘ │ └─────────────────┘ │
│ │ │
│ ┌──────────▼────────────┐ │
│ │ Handover │ │
│ │ (IWLAN ◄─► Cellular) │ │
│ └───────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
状态转移:
- Connecting ➜ Connected: 数据连接成功
- Connecting ➜ Disconnected: 连接失败或被拒绝
- Connected ➜ Handover: IWLAN/Cellular 切换
- Handover ➜ Connected: Handover 成功
- Connected ➜ Disconnecting: 接收到断开请求
- Disconnecting ➜ Disconnected: 实际断开完成
- Any state ➜ Disconnected: 紧急断开(失败、超时等)
2.2 完整流程
┌─────────────────────────────────────────────────────────┐
│ 1️⃣ 应用请求 │
├─────────────────────────────────────────────────────────┤
│ 应用通过 ConnectivityManager.requestNetwork() 请求网络 │
│ │
│ NetworkRequest request = new NetworkRequest.Builder() │
│ .addCapability(NET_CAPABILITY_INTERNET) │
│ .addTransportType(TRANSPORT_CELLULAR) │
│ .build(); │
│ ConnectivityManager.requestNetwork(request, callback) │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 2️⃣ ConnectivityService 评分 │
├─────────────────────────────────────────────────────────┤
│ - 对所有可用网络提供者评分 │
│ - Telephony score vs WiFi score vs VPN score │
│ - 选择得分最高的网络 │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 3️⃣ TelephonyNetworkFactory 处理 │
├─────────────────────────────────────────────────────────┤
│ - 接收到 NetworkRequest │
│ - 转发给 DataNetworkController │
│ - addNetworkRequest(request) │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 4️⃣ DataNetworkController 分析 │
├─────────────────────────────────────────────────────────┤
│ - 检查请求的 Capability 类型 │
│ ├─ NET_CAPABILITY_INTERNET? 需要 Internet APN │
│ ├─ NET_CAPABILITY_MMS? 需要 MMS APN │
│ ├─ NET_CAPABILITY_IMS? 需要 IMS APN │
│ └─ NET_CAPABILITY_XCAP? 需要 XCAP APN │
│ │
│ - 查询数据库获取所有可用 APN 列表 │
│ ├─ Carriers 表 (来自 Telephony Provider) │
│ ├─ 过滤: 合适的网络类型 │
│ └─ 排序: 优先级、最近使用等 │
│ │
│ - 找到满足条件的 DataProfile │
│ ├─ ApnSetting: 旧式 (2G/3G/4G) │
│ └─ TrafficDescriptor: 新式 (5G SA URSP) │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 5️⃣ 创建 DataNetwork 实例 │
├─────────────────────────────────────────────────────────┤
│ new DataNetwork( │
│ phone, // Phone 对象 │
│ looper, // 事件循环 │
│ dataServiceManagers, // Modem 接口 │
│ dataProfile, // APN/TrafficDescriptor │
│ networkRequestList, // 已附加的请求列表 │
│ transport, // TRANSPORT_WWAN/WLAN │
│ dataAllowedReason, // 为什么允许建立 │
│ callback // 状态通知回调 │
│ ); │
│ │
│ 进入 Connecting 状态 │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 6️⃣ 准备数据参数 │
├─────────────────────────────────────────────────────────┤
│ - 确定网络类型 (LTE, 5G NR, IWLAN) │
│ - 获取漫游状态 │
│ - 是否允许数据漫游 │
│ - 获取 PDU Session ID (5G) │
│ - 获取 Slice 信息 (5G) │
│ - 获取 Traffic Descriptor (5G URSP) │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 7️⃣ DataServiceManager.setupDataCall() │
├─────────────────────────────────────────────────────────┤
│ setupDataCall( │
│ accessNetworkType=LTE/NR/IWLAN, │
│ dataProfile={apn, protocol, auth, ...}, │
│ isRoaming=true/false, │
│ allowRoaming=true/false, │
│ reason=NORMAL/HANDOVER, │
│ linkProperties=null (or handover data), │
│ pduSessionId=1-15 (5G) or -1, │
│ sliceInfo=null (or 5G slice), │
│ trafficDescriptor=null (or URSP info), │
│ matchAllRuleAllowed=true/false │
│ ); │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 8️⃣ CellularDataService.setupDataCall() │
├─────────────────────────────────────────────────────────┤
│ - 从 DataService 转调到 RIL │
│ - mPhone.mCi.setupDataCall( │
│ accessNetworkType, │
│ dataProfile, │
│ allowRoaming, │
│ reason, │
│ linkProperties, │
│ pduSessionId, │
│ sliceInfo, │
│ trafficDescriptor, │
│ matchAllRuleAllowed │
│ ); │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 9️⃣ RadioDataProxy.setupDataCall() │
├─────────────────────────────────────────────────────────┤
│ 选择 HAL 版本并调用: │
│ - HAL 1.6+: setupDataCall_1_6() │
│ ├─ TrafficDescriptor 支持 (5G URSP) │
│ └─ Optional<SliceInfo> 支持 │
│ │
│ - HAL 1.5: setupDataCall_1_5() │
│ ├─ PDU Session ID 支持 │
│ └─ Link Properties 支持 │
│ │
│ - HAL 1.4: setupDataCall_1_4() │
│ └─ 基础 PDP 建立 │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ 🔟 Modem 硬件处理 │
├─────────────────────────────────────────────────────────┤
│ Modem 执行: │
│ 1. 检查 Access Point (APN, TrafficDescriptor) │
│ 2. 选择合适的 QoS (Quality of Service) │
│ 3. 发送 NAS 信息给网络 │
│ 4. 等待 NAS Accept (包含 PDP Context, IP, DNS 等) │
│ 5. 分配 CID (Context ID) 标识此连接 │
│ 6. 激活无线链路层 │
└──────────────┬──────────────────────────────────────────┘
│
┌──────────────▼──────────────────────────────────────────┐
│ ⑪ 数据响应处理 │
├─────────────────────────────────────────────────────────┤
│ DataCallResponse 包含: │
│ - resultCode: 成功/失败 │
│ - cid: Context ID │
│ - failCause: 失败原因 (if failed) │
│ - addresses: 分配的 IP 地址 (IPv4 或 IPv6) │
│ - dnses: DNS 服务器列表 │
│ - gateways: 网关地址 │
│ - pcscfAddresses: P-CSCF (IMS) │
│ - mtu: 最大传输单元 │
│ - defaultQos: 默认 QoS 参数 │
│ - sliceInfo: 分配的网络切片 (5G) │
│ - pduSessionId: PDU 会话 ID (5G) │
│ - handoverFailureMode: Handover 失败模式 │
│ - trafficDescriptors: 流量描述符列表 (5G) │
└──────────────┬──────────────────────────────────────────┘
│ 成功?
┌──────┴──────┐
│ YES │ NO │
▼ ▼ ▼
3. DataProfile (数据配置文件)
3.1 DataProfile 的构成
// DataProfile 包含:
public class DataProfile {
// 1. APN 配置 (ApnSetting) - 针对 4G/LTE 及以下
private ApnSetting mApnSetting;
├─ apnName: "internet.xyz.com"
├─ apnTypeBitmask: TYPE_DEFAULT (for Internet)
├─ protocol: PROTOCOL_IPV4V6
├─ roamingProtocol: PROTOCOL_IP
├─ authType: AUTH_TYPE_PAP/CHAP
├─ user: "username" (if needed)
├─ password: "password" (if needed)
├─ mtuV4: 1500
├─ mtuV6: 1500
├─ maxConns: 10
├─ maxConnsTime: 0
├─ waitTime: 0
└─ enabled: true
// 2. Traffic Descriptor - 针对 5G SA (URSP)
private TrafficDescriptor mTrafficDescriptor;
├─ dataNetworkName: "ims" / "internet" (DNN)
└─ osAppId: byte[] (Operating System App ID)
// 3. 元数据
private int mType; // TYPE_COMMON, TYPE_3GPP, TYPE_3GPP2
private boolean mPreferred; // 最近使用过
}
3.2 APN 类型与用途
TYPE_DEFAULT (0x1)
├─ 用途: 普通 Internet 数据
├─ APN: "internet" / "4gnet" / "wap" 等
└─ 优先级: 最高 (用于一般数据)
TYPE_MMS (0x2)
├─ 用途: 彩信 (Multimedia Message Service)
├─ APN: "mms" / "mms.xyz.com"
└─ 特点: 需要临时激活 (DSDS 设备)
TYPE_SUPL (0x4)
├─ 用途: 定位辅助 (SUPL - Secure User Plane Location)
├─ APN: "supl" / "sprintpcs"
└─ 用于: GPS 辅助定位 (A-GPS)
TYPE_DUN (0x8)
├─ 用途: 数据拨号 (Dial-Up Network)
├─ 说明: 旧式功能,现在很少用
TYPE_IMS (0x10)
├─ 用途: IP Multimedia Subsystem (VoLTE/VoWiFi)
├─ APN: "ims" / "ims.xyz.com"
└─ 优先级: 高 (语音通话通过 IMS)
TYPE_CBS (0x20)
├─ 用途: Cell Broadcast Service (公共警报)
├─ 说明: 系统级功能
TYPE_IA (0x40)
├─ 用途: 初始附着 (Initial Attach)
├─ 说明: 设备开机时首次附着
TYPE_XCAP (0x200)
├─ 用途: XML Configuration Access Protocol
├─ 用于: 增强型通话功能配置
TYPE_FOTA (0x100)
├─ 用途: Firmware Over The Air 更新
├─ 说明: 设备固件更新
4. 数据连接状态通知
// 应用层监听数据连接状态
public interface TelephonyCallback {
public interface DataConnectionStateListener {
void onDataConnectionStateChanged(
@DataState int state, // DISCONNECTED/CONNECTING/CONNECTED/SUSPENDED/HANDOVER
@NetworkType int networkType // NETWORK_TYPE_LTE/NR/...
);
}
}
// 状态常量
@DataState int state:
├─ DATA_DISCONNECTED = 0
├─ DATA_CONNECTING = 1
├─ DATA_CONNECTED = 2
├─ DATA_SUSPENDED = 3
├─ DATA_HANDOVER_IN_PROGRESS = 4
└─ DATA_UNKNOWN = -1
// 网络类型
@NetworkType int:
├─ NETWORK_TYPE_GPRS = 1
├─ NETWORK_TYPE_EDGE = 2
├─ NETWORK_TYPE_UMTS = 3
├─ NETWORK_TYPE_CDMA = 4
├─ NETWORK_TYPE_EVDO_0 = 5
├─ NETWORK_TYPE_LTE = 13
├─ NETWORK_TYPE_NR = 20 (5G SA)
├─ NETWORK_TYPE_IWLAN = 18
└─ ... 更多类型
5. PDP 上下文和 CID
PDP (Packet Data Protocol) 上下文 = 一个数据连接会话
PDP 上下文的关键参数:
┌──────────────────────────────┐
│ CID (Context ID) │ 标识符 (1-11 通常)
│ Access Point (APN) │ internet/mms/ims
│ PDN Type (PDP Type) │ IPv4/IPv6/IPv4v6
│ QoS (Quality of Service) │ 优先级、速率限制
│ PDU Session ID │ 5G 特定 (1-15)
│ UE IP Address │ 设备 IP (v4 或 v6)
│ GGSN/PGW Address │ 网关地址
│ DNS Servers │ DNS1, DNS2
│ MTU (Maximum Transmission) │ 最大包大小 (通常 1500)
│ P-CSCF Address │ IMS 相关
│ Slice Info (S-NSSAI) │ 5G 网络切片
└──────────────────────────────┘
实际建立过程:
LTE 网络:
User Equipment Network
│ │
├─ ATTACH REQUEST ──────►│
│ │
│◄─ ATTACH ACCEPT ──────┤ (包含 PDP Context)
│ │
├─ ACTIVATE PDP CONTEXT ┤
│ REQUEST ───────────►│
│ │
│◄─ ACTIVATE PDP CONTEXT┤ (CID=1, IP: 10.0.0.1, DNS)
│ ACCEPT ─────────────┤
│ │
└ Data Bearer 建立 ────►│
5G NR:
User Equipment Network (5GC)
│ │
├─ REGISTRATION REQUEST┤
│ ────────────────────►│
│ │
│◄─ REGISTRATION ACCEPT┤ (包含 GUTI)
│ ────────────────────┤
│ │
├─ PDU SESSION ESTABLISH
│ REQUEST (DNN: internet)
│ ────────────────────►│
│ │
│◄─ PDU SESSION ESTABLISH
│ ACCEPT ─────────────┤ (PSI=1, IP: 10.0.0.2)
│ │
└ Data Bearer 建立 ────►│
6. 数据连接失败和重试
// 失败原因 (DataFailCause)
public enum DataFailCause {
// 成功状态
NONE,
// 网络拒绝
OPERATOR_BARRED, // 运营商禁止
INSUFFICIENT_RESOURCES, // 资源不足
MISSING_UNKNOWN_APN, // APN 不存在
UNKNOWN_PDP_ADDRESS_TYPE, // 地址类型错误
USER_AUTHENTICATION_FAILED, // 用户认证失败
ACTIVATION_REJECT_GGSN, // 网关拒绝
SERVICE_OPTION_NOT_SUPPORTED,// 服务不支持
// 本地错误
NO_RETRY_FAILURE, // 不重试的失败
RADIO_OFF, // 飞行模式
ROAMING_NOT_ALLOWED, // 漫游禁用
HANDOVER_FAILURE, // Handover 失败
PERM_FAILURE, // 永久失败
// 网络问题
SIGNAL_LOST, // 信号丢失
PREEEMPTED, // 被抢占
CONGESTION, // 网络拥塞
// 超时
TIMED_OUT, // 超时
// 5G 特定
SLICE_REJECTED, // 网络切片被拒
MATCH_ALL_RULE_NOT_ALLOWED, // URSP 规则不匹配
}
// 重试策略
dataSetupRetryEntry = new DataRetryEntry() {
int failCause; // 失败原因
int state; // FAILED, SUCCEEDED, CANCELLED
long retryDelayMillis; // 重试延迟
int retryCount; // 已重试次数
}
// 重试逻辑
if (failCause == RADIO_OFF || failCause == ROAMING_NOT_ALLOWED) {
// 不重试,等待用户操作
return NO_RETRY;
} else if (failCause == INSUFFICIENT_RESOURCES) {
// 指数退避重试: 3s, 6s, 12s, ...
retryDelayMillis = calculateBackoffDelay(retryCount);
} else if (failCause == TIMED_OUT) {
// 立即重试 (最多 N 次)
retryDelayMillis = 0;
} else {
// 根据 CarrierConfig 规则
retryDelayMillis = getRetryDelayFromConfig(failCause);
}
7. 多卡(DSDS)下的数据连接
DSDS 设备上的复杂性:
┌─ SIM1 (DDS - Default Data Subscription)
│ ├─ DataNetworkController1
│ ├─ Modem1 允许 PS 附着
│ ├─ 可以建立:
│ │ ├─ Internet APN (DDS 优先)
│ │ ├─ IMS APN
│ │ └─ SUPL APN
│ └─ 其他请求: 允许建立
│
└─ SIM2 (NIDS - Non-Default Data Subscription)
├─ DataNetworkController2
├─ Modem2 PS 附着受限 (DSDS)
│ └─ 仅当 Modem1 无 PS 时才激活
├─ 可以建立:
│ ├─ MMS (临时激活 Modem2)
│ └─ 其他 (需检查是否需要激活)
└─ Internet 数据: 通常不允许 (除非 DDS 切换)
MMS 在 DSDS 上的特殊处理:
MMS 请求来到:
↓
ConnectivityService 选择最佳网络
↓
如果是 SIM2 的 MMS:
├─ PhoneSwitcher 激活 Modem2: setDataAllowed(1)
├─ MMS APN 在 Modem2 上建立
├─ MMS 发送完成
└─ PhoneSwitcher 停用 Modem2: setDataAllowed(0)
8. 数据连接的关键 API 和事件
// Framework 级别的关键接口
// 1. DataNetworkController 回调
public interface DataNetworkCallback {
void onConnected(DataNetwork dataNetwork);
void onAttachFailed(DataNetwork dataNetwork, NetworkRequestList requestList);
void onDisconnected(DataNetwork dataNetwork, int cause, int tearDownReason);
void onValidationStatusChanged(DataNetwork dataNetwork, int status, Uri redirectUri);
void onSuspendedStateChanged(DataNetwork dataNetwork, boolean suspended);
void onHandoverSucceeded(DataNetwork dataNetwork);
}
// 2. DataServiceCallback (来自 Modem)
public interface DataServiceCallback {
void onSetupDataCallComplete(int resultCode, DataCallResponse response);
void onDeactivateDataCallComplete(int resultCode);
void onDataCallListChanged(List<DataCallResponse> dataCallList);
void onStartHandoverComplete(int resultCode);
}
// 3. 应用级别的监听
TelephonyManager.registerTelephonyCallback(executor, callback);
├─ callback.onDataConnectionStateChanged(state, networkType)
├─ callback.onPreciseDataConnectionStateChanged(pdcs)
└─ callback.onDataActivity(dataActivity) // 数据流量活动
// 4. 应用级别的控制
// 启用/禁用移动数据
TelephonyManager.setDataEnabled(true);
// 设置漫游数据
TelephonyManager.setDataRoamingEnabled(true);
// 启用/禁用特定 APN
setCarrierDataEnabled(true); // 所有 APN
9. 数据连接的性能指标
关键性能指标:
1. 连接建立时间
├─ Framework -> Modem: 50-100ms
├─ Modem -> Network: 200-1000ms (4G)
├─ 总计: 250-1100ms (通常)
└─ 优化: 预连接 (Pre-attach)
2. 断开延迟
├─ 优雅关闭: 100-300ms
├─ 强制关闭: 50-100ms
└─ Handover 时: 尽可能快 (< 200ms)
3. 数据速率
├─ 4G (LTE): 50-300 Mbps
├─ 5G (NSA): 200-500 Mbps
├─ 5G (SA): 300-1000+ Mbps
└─ WiFi: 50-600 Mbps
4. 功耗
├─ RRC Connected: ~100-200 mA (传输中)
├─ RRC Idle: ~5-20 mA (待机)
└─ 5G: 相对更高 (Modem 功耗)
总结:蜂窝数据连接管理的核心要点
┌────────────────────────────────────────────────────────┐
│ 1. 分层架构 │
│ - 应用 → Framework → Telephony → Modem │
│ - 每层有明确的职责和接口 │
│ │
│ 2. 状态机驱动 │
│ - DataNetwork: Connecting → Connected → ... │
│ - 明确的状态转移和事件处理 │
│ │
│ 3. 多重匹配 │
│ - NetworkRequest 与 DataProfile 匹配 │
│ - 根据 Capability 选择合适 APN │
│ │
│ 4. 异步处理 │
│ - 所有操作都是异步的(Callback) │
│ - Handler 消息队列驱动 │
│ │
│ 5. 错误处理与重试 │
│ - 24 种以上失败原因分类 │
│ - 智能重试策略(指数退避、延迟等) │
│ │
│ 6. 多维度支持 │
│ - 4G/LTE 的 PDP Context │
│ - 5G 的 PDU Session │
│ - IWLAN Handover 支持 │
│ - DSDS 多卡管理 │
│ │
│ 7. QoS 和 SLA │
│ - 优先级队列 │
│ - 带宽管理 │
│ - 网络切片(5G) │
└────────────────────────────────────────────────────────┘
这就是 Android 蜂窝数据连接管理的完整系统!它是一个复杂但设计精良的系统,确保了在各种场景下的稳定数据连接。