Android Telephony 核心流程面试准备

7 阅读5分钟

一、系统架构与基础概念

1. Telephony 整体架构

  • 三层结构:Java Framework (Telephony) → HAL (HIDL/AIDL) → Modem RIL
  • 关键角色
    • Phone - 逻辑手机对象
    • RIL (Radio Interface Layer) - 与 Modem 通信的中介
    • ServiceStateTracker - 网络状态跟踪
    • PhoneSwitcher - 多卡协调
    • DataNetworkController - 数据网络管理

2. 多卡(DSDS)管理

  • SubId vs PhoneId 的映射关系
  • 默认数据卡、语音卡、彩信卡 的选择与切换
  • MultiSimSettingController 的职责

3. Subscription 管理

  • SubscriptionManagerService 的核心职责
  • 卡槽状态变化处理
  • 默认设置的持久化

二、常见流程深度题目

问题 1:来电显示流程(Call Indication)

关键点

  1. Modem 上报 RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
  2. RadioIndication.callStateChanged() 接收
  3. RIL.processIndication() 处理
  4. Phone.notifyCallStateChanged() 通知各个模块
  5. 多卡设备如何区分来电是来自哪张卡

可能的深入问题

  • 如何处理多卡同时有来电的情况?
  • 来电通知的优先级如何确定?
  • 振铃音如何选择(哪张卡的铃声)?

代码关键路径

RadioIndication.callStateChanged()
  → RIL.processIndication()
  → Phone.notifyCallStateChanged()
  → PhoneNotifier.notifyCallStateChanged()
  → TelephonyRegistryManager.notifyCallStateChanged()

问题 2:发送短信流程(Send SMS)

关键点

  1. 应用调用 SmsManager.sendTextMessage(subId, ...) 指定副卡
  2. SmsSender 获取对应副卡的 Phone 对象
  3. GsmSMSDispatcherCdmaSMSDispatcher 处理
  4. 通过 RIL 发送给 Modem
  5. Modem 返回结果,通过 PendingIntent 回调

可能的深入问题

  • 如何确保副卡彩信也能正确发送?
  • 短信失败重试机制?
  • 如何处理运营商特定的发送参数?

代码关键路径

SmsManager.sendTextMessage(subId, ...)
  → SmsSender.sendMessage()
  → GsmSMSDispatcher.sendMessage()
  → RIL.sendSMS()
  → RadioResponse.sendSmsResponse()
  → PendingIntent callback

问题 3:副卡彩信收发流程(Secondary SIM MMS)

关键点

  1. 发送:指定 subId → MmsManager → MmsServiceBroker → RIL → MMSC
  2. 接收:WAP Push → 识别 subId → 下载 MMS → 存储到对应卡的数据库
  3. 关键: 多卡时数据连接的切换管理
  4. 权限检查: SEND_SMS/RECEIVE_MMS 权限

可能的深入问题

  • MMS 如何在多卡设备上优先级选择?
  • MMS 数据连接与默认数据卡冲突如何处理?
  • 如何从 WAP Push 的 slotIndex 映射到 subId?

代码关键路径

MmsManager.sendMultimediaMessage(subId, ...)
  → MmsServiceBroker.sendMessage()
  → CarrierMessagingService.onSendMms()
  → 建立 MMS 数据连接
  → 通过 HTTP 发送 PDU 到 MMSC

问题 4:网络状态变化流程(Network State Change)

关键点

  1. Modem 上报网络注册状态变化
  2. RadioIndication.networkStateChanged()
  3. ServiceStateTracker 更新网络状态
  4. Phone.notifyServiceStateChanged()
  5. 触发 UI 更新(信号强度、网络制式等)

可能的深入问题

  • 如何区分 2G/3G/4G/5G 网络制式?
  • 漫游状态如何判断和显示?
  • 多卡时网络状态的独立性?

问题 5:数据连接建立流程(Data Network Setup)

关键点

  1. 应用请求数据连接(Internet)
  2. ConnectivityManager 向 Telephony 请求
  3. DataNetworkController 选择合适的 APN
  4. TelephonyNetworkFactory 创建 DataNetwork
  5. 通过 RIL 向 Modem 发送 setupDataCall()
  6. Modem 建立 PDP Context,返回网络参数
  7. 系统更新 LinkProperties,通知应用

可能的深入问题

  • 如何选择最合适的 APN(多个 APN 配置时)?
  • 副卡数据连接建立时是否需要切换默认数据卡?
  • 数据连接失败的重试策略?
  • 4G 转 5G 的数据连接是否需要重新建立?

代码关键路径

ConnectivityManager.requestNetwork()
  → TelephonyNetworkFactory.requestNetwork()
  → DataNetworkController.createDataNetwork()
  → DataProfileManager.selectDataProfile()
  → RIL.setupDataCall()
  → RadioResponse.setupDataCallResponse()
  → DataNetwork.onSetupDataCallSuccess()

问题 6:PhoneNotifier 与状态通知(PhoneNotifier & State Notification)

关键点

  1. 为什么需要 PhoneNotifier? - 解耦 Phone 逻辑与系统通知
  2. DefaultPhoneNotifier 实现
  3. TelephonyRegistryManager 负责广播
  4. 监听者模式 - 各模块注册 Registrant 接收状态变化

可能的深入问题

  • 如何避免通知风暴(频繁更新状态导致的性能问题)?
  • 通知的线程安全性如何保证?
  • 多卡时如何避免通知混乱?

问题 7:RIL 异步处理模型(RIL Async Model)

关键点

  1. 命令队列 - RequestInfo 链表管理待发送的命令
  2. Token 机制 - 每个请求有唯一 token,响应时通过 token 匹配
  3. 异步响应 - RIL_onRequestComplete()
  4. Wake Lock - 防止长时间请求时系统睡眠

可能的深入问题

  • 如何处理 Modem 响应超时?
  • Modem 发生 Crash 时如何恢复?
  • 队列中有多个请求时,哪个优先执行?

三、数据恢复与容错机制

DataStallRecoveryManager

  • 数据连接卡死(Data Stall)的检测
  • 4 级递进恢复机制:
    1. GET_DATA_CALL_LIST
    2. CLEANUP
    3. RADIO_RESTART
    4. RESET_MODEM

RescueParty

  • 系统级容错
  • 当频繁崩溃时,尝试重置设置、清除数据、工厂恢复

四、多卡专有流程

问题 8:多卡数据切换流程

当用户切换默认数据卡时:

  1. 系统更新 Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION
  2. MultiSimSettingController 监听到变化
  3. 释放旧数据卡的数据连接
  4. 在新数据卡上重建数据连接
  5. 通知 ConnectivityService 切换

可能的深入问题

  • 切换过程中如何避免网络断连?
  • 应用正在传输数据时切换如何处理?
  • 两张卡都是 4G 时,切换延迟多长时间可接受?

五、面试常见考点总结表

考点难度关键词
Phone 对象与 RIL 通信⭐⭐Token、异步、RequestInfo
来电显示与通知⭐⭐⭐RadioIndication、PhoneNotifier、Registrant
短信发送与回调⭐⭐⭐SubId、PendingIntent、RIL
副卡彩信⭐⭐⭐⭐MMS 网络切换、MMSC、运营商服务
数据网络建立⭐⭐⭐⭐APN 选择、PDP Context、LinkProperties
多卡数据切换⭐⭐⭐⭐⭐PhoneSwitcher、优先级、并发处理
HIDL/AIDL 迁移⭐⭐⭐兼容层、版本管理
数据恢复机制⭐⭐⭐⭐DataStall、Recovery Actions、RescueParty

六、面试高频问题预测

  1. "解释一下来电时系统的调用链" → 从 RIL 到 UI 更新的完整路径

  2. "多卡设备副卡发送短信如何确保发送到正确的卡?" → SubId 的作用、RIL 的处理

  3. "为什么需要 PhoneNotifier?直接让 Phone 通知不行吗?" → 解耦、系统架构分层

  4. "数据连接卡死(Data Stall)了如何恢复?" → DataStallRecoveryManager 的 4 级机制

  5. "Modem 向系统上报的无线指示(Unsolicited Indication)有多少种?" → RadioIndication 中的各个回调方法

  6. "HIDL 和 AIDL 在 RIL 中的区别是什么?" → 接口定义方式、版本管理、兼容层

  7. "多卡时默认数据卡与 MMS 数据连接如何协调?" → PhoneSwitcher 的作用、网络请求优先级

  8. "RIL 中如何确保异步命令与响应一一对应?" → Token 机制、RequestInfo 队列


七、学习建议

  1. 从简到繁:先掌握单卡流程,再学多卡协调
  2. 代码阅读顺序
    • 先读 Java Framework 层的接口
    • 再看 RIL 的具体实现
    • 最后理解 HAL 的异步通信
  3. 关键文件要深入
    • RIL.java - 核心枢纽
    • Phone.java - 逻辑手机
    • PhoneSwitcher.java - 多卡协调
    • ServiceStateTracker.java - 网络状态
    • DataNetworkController.java - 数据连接

祝您面试顺利!如果需要深入讲解某个具体流程,我可以为您查看对应的代码并详细解析。