RIL (Radio Interface Layer) 深度架构设计

Android RIL(Radio Interface Layer)全面概述和知识要点(3万字长文) 在 Android 系统这个庞大而复杂的体系里,RIL(Radio Interface Layer,无线接口层)绝对是个关键角色。简单来讲,它就像一座桥梁,一头连着手机基带,另一头接着上层应用 ,在应用程序和调制解调器(Modem)之间搭建起了信息交流的通道。想象一下,咱们在手机上点击拨号按钮,或者编辑一条短信发送出去,这些操作产生的请求并不会直接到达手机的基带处理器。而是先由 RIL 接手,它把这些来自上层应用程序的请求,像拨号、发送短信这类,巧妙地转换成能够和基带处理器顺畅交互的命令。 阅读详情

description: “RIL (Radio Interface Layer) 深度架构设计——Android 框架与 Modem 之间的唯一桥梁,涵盖 HIDL→AIDL 双栈适配、异步请求-响应模型、RILRequest 对象池、UNSOL 上行通知、WakeLock 防护、Radio HAL 版本回退兼容策略。”

RIL (Radio Interface Layer) 深度架构设计

RIL 是整个 Telephony 框架中最核心、最底层的组件。它位于 Framework 与 Vendor Modem 之间,承担着"翻译官"和"调度员"的双重角色——将 Java 层的调用翻译为硬件可以理解的 AT 命令/协议消息,并将 Modem 的响应和主动上报转发回 Framework。

没有 RIL,Phone 无法打电话、ServiceStateTracker 无法获取网络状态、DataNetwork 无法建立数据连接。 它是整条调用链的"最后一公里"。

设计理念: RIL 的设计是一个经典的"中间层"架构,Google 在此投入了大量工程努力来处理异步通信、跨进程边界(Treble)、电源管理(WakeLock)以及 HAL 版本兼容性。从 HIDL 到 AIDL 的迁移路径是整个 Android HAL 生态的缩影。

1. 核心职责

  1. 命令翻译与转发:将 CommandsInterface 中的 Java 方法调用(如 getVoiceRegistrationState())转换为 HAL 层调用
  2. 响应分发:将 HAL 层返回的数据分发给对应的 Message.callback
  3. 主动上报 (UNSOL) 处理:Modem 主动上报的网络变化、来电、信号强度等事件分发到对应 Handler
  4. WakeLock 电源管理:确保在处理关键 RIL 请求时设备不会进入休眠
  5. HAL 服务生命周期管理:RadioProxy 的死亡监听、重连、服务禁用策略
  6. HAL 版本兼容:新旧 HAL 版本之间的 fallback 兼容策略

2. 核心类与源码锚点 (Source Code Anchors)

  • [RIL.java](file:///d:/Resource/Android%2016/android-16/frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java):核心 RIL 实现类(11000+ 行)。继承 BaseCommands,实现 CommandsInterface。
  • [CommandsInterface.java](file:///d:/Resource/Android%2016/android-16/frameworks/base/telephony/java/com/android/internal/telephony/CommandsInterface.java):RIL 与上层模块之间的接口契约。Phone 模块只依赖此接口,不直接依赖 RIL 实现。
  • [RILConstants.java](file:///d:/Resource/Android%2016/android-16/frameworks/base/telephony/java/com/android/internal/telephony/RILConstants.java):定义了所有 RIL_REQUEST_*、RIL_UNSOL_* 常量及错误码。
  • [RILRequest.java](file:///d:/Resource/Android%2016/android-16/frameworks/opt/telephony/src/java/com/android/internal/telephony/RILRequest.java)(内部类):封装单次 RIL 请求的数据结构,使用对象池(sPool)复用。
  • [RadioResponse.java](file:///d:/Resource/Android%2016/android-16/frameworks/opt/telephony/src/java/com/android/internal/telephony/RadioResponse.java):HAL 层同步响应的回调接口实现。所有 process*Response() 方法在此。
  • [RadioIndication.java](file:///d:/Resource/Android%2016/android-16/frameworks/opt/telephony/src/java/com/android/internal/telephony/RadioIndication.java):HAL 层主动上报(UNSOL)的回调接口实现。
  • [RadioServiceProxy.java](file:///d:/Resource/Android%2016/android-16/frameworks/opt/telephony/src/java/com/android/internal/telephony/RadioServiceProxy.java):HIDL 和 AIDL 的双栈代理,透明切换底层 HAL 版本。
  • 硬件层:[rild.c](file:///d:/Resource/Android%2016/android-16/hardware/ril/rild/rild.c)(守护进程)、[ril_service.cpp](file:///d:/Resource/Android%2016/android-16/hardware/ril/libril/ril_service.cpp)(C++ 层 HAL 实现)

3. Google 设计技巧深入分析

3.1 8 大 HAL Service 拆分 — 关注点分离

Android 16 将原来的单一 IRadio HAL 接口拆分为 8 个独立服务:

public static final int MIN_SERVICE_IDX = HAL_SERVICE_RADIO;    // 0
public static final int MAX_SERVICE_IDX = HAL_SERVICE_IMS;      // 7
// HAL_SERVICE_RADIO, HAL_SERVICE_DATA, HAL_SERVICE_IMS,
// HAL_SERVICE_MESSAGING, HAL_SERVICE_MODEM, HAL_SERVICE_NETWORK,
// HAL_SERVICE_SIM, HAL_SERVICE_VOICE

每个服务对应独立的 Response 和 Indication 回调:

private RadioResponse mRadioResponse;
private RadioIndication mRadioIndication;
private DataResponse mDataResponse;
private DataIndication mDataIndication;
private ImsResponse mImsResponse;
private ImsIndication mImsIndication;
// ... 共 8 对 Response/Indication

Google设计技巧 #1 — 按功能域拆分的 HAL 服务 (Domain-Specific HAL Services):
将单一 IRadio 拆分为 8 个独立服务,每个服务拥有独立的 getService()、独立的 DeathRecipient、独立的回调接口。这意味着:

  • OEM 可以不实现 HAL_SERVICE_SIM 而只实现 HAL_SERVICE_VOICE(例如纯数据设备)
  • 某个服务 crash 后只需要重启该服务,不影响其他功能
  • 并发性能更好——不同服务在不同 Binder 线程上独立处理

同时通过 FEATURES_TO_SERVICES 映射表关联 PackageManager.FEATURE_TELEPHONY_*,实现按设备能力启用/禁用对应服务。

3.2 RadioProxy — HIDL/AIDL 双栈适配

RIL.java 中同时存在两种 proxy 获取方式:

// HIDL 方式 (老路径)
private volatile IRadio mRadioProxy = null;

public synchronized IRadio getRadioProxy() {
   
   
    if (mRadioProxy != null) return mRadioProxy;
    // 从最新版本逐级回退
    mRadioProxy = android.hardware.radio.V1_6.IRadio.getService(HIDL_SERVICE_NAME[mPhoneId], ...);
    if (mRadioProxy == null) {
   
   
        mRadioProxy = android.hardware.radio.V1_5.IRadio.getService(...);
    }
    if (mRadioProxy == null) {
   
   
        mRadioProxy = android.hardware.radio.V1_4.IRadio.getService(...);
    }
    // ... 继续回退到 V1_0
}

而 AIDL 服务通过 RadioServiceProxy 统一封装:

private SparseArray<RadioServiceProxy> mServiceProxies = new SparseArray<>();

Google设计技巧 #2 — HIDL→AIDL 渐进迁移的双栈并行策略:
RadioServiceProxy 是 HIDL 和 AIDL 的统一代理,内部持有 IHwRadio 和 IRadioAidl 两个引用,根据目标 HAL 版本自动选择使用哪个。这允许 OEM 逐步迁移:Voice 模块使用新 AIDL HAL,而 Data 模块仍使用旧 HIDL HAL 也无妨。RadioServiceProxy 还支持 isAidl() / getHidl() 方法,让上层代码可以按需判断:

if (serviceProxy.isAidl()) {
    
    
    IRadioAidl aidl = serviceProxy.getAidl();
    aidl.someMethod(...);
} else {
    
    
    IHwRadio hidl = serviceProxy.getHidl();
    hidl.someMethod(...);
}

3.3 RILRequest — 对象池复用的请求封装

RILRequest 是 RIL 中最精巧的数据结构设计:

static RILRequest obtain(int request, Message result, WorkSource workSource) {
   
   
    RILRequest rr = null;
    synchronized (sPoolSync) {
   
   
        if (sPool != null) {
   
   
            rr = sPool;
            sPool = rr.mNext;
            rr.mNext = null;
            sPoolSize--;
        }
    }
    if (rr == null) {
   
   
        rr = new RILRequest();
    }
    rr.init(request, result, workSource);
    return rr;
}

Google设计技巧 #3 — 对象池 (Object Pool) + WakeLock 绑定:
RILRequest 使用单链表实现的对象池(sPool),而非每次 new 新对象。在高频场景下(如轮询信号强度每秒一次),这可以显著减少 GC 压力。

每发送一个 RILRequest 就持有一个 WakeLock,防止 CPU 在处理关键通信命令时休眠。mRequestList (SparseArray<RILRequest>) 按 serial 号索引所有未完成的请求:

SparseArray<RILRequest> mRequestList = new SparseArray<>();

EVENT_WAKE_LOCK_TIMEOUT 机制防止 WakeLock 被永久持有——如果 Modem 长时间无响应(DEFAULT_WAKE_LOCK_TIMEOUT_MS),系统会释放 WakeLock 并记录异常。

3.4 双向通道模型 — 同步响应 + 异步上报 (UNSOL)

RIL 使用双通道与 Modem 通信:

Framework (Java)                              Modem (C/C++)
┌──────────────┐        下行命令 (SOLICITED)        ┌──────────┐
│  RIL.java    │ ────────setupDataCall()──────────→ │  rild    │
│  (11000+ 行) │                                    │  daemon  │
│              │ ←──────onDataCallListChanged()──── │          │
└──────────────┘       上行通知 (UNSOLICITED)        └──────────┘
  • 下行命令 (Solicited):Framework → Modem。每条命令携带一个 serial 号,Modem 处理完后通过 RadioResponse 回传结果
  • 上行通知 (Unsolicited):Modem → Framework。无需 Framework 主动请求,Modem 通过 RadioIndication 主动上报
// 发送下行命令
private void send(RILRequest rr) {
   
   
    addRequest(rr);  // 加入 mRequestList,获取 serial 号
    
深入了解Android RIL层源码实现 在移动通信设备中,无线接口层(Radio Interface Layer,简称RIL)扮演着至关重要的角色。RIL是移动设备软件架构中的关键组件,它作为中介层,负责协调硬件(如基带处理器)与高级服务(如电话和数据通信服务)之间的通信。RIL的定义主要涉及到它的基本功能和它如何被设计来提供与无线硬件的交互。它抽象化了底层无线通信的复杂性,为上层应用提供了一组简洁明了的接口。因此,无论是操作系统还是应用程序,都可以通过RIL与手机的无线模块进行通信。 阅读详情

相关推荐

DEAP数据集实战指南:从脑电信号到情绪分类的完整流程解析

本文提供了DEAP数据集在脑电信号情绪识别领域的完整实战指南。详细解析了数据下载、结构理解、频带功率特征提取等核心步骤,并演示了如何构建和评估机器学习分类模型,为研究者实现从原始脑电信号到情绪分类的完整流程提供了清晰路径。

jj890的博客 895

电子工程师必看:2024年IPC-A-610J和J-STD-001J新标准到底更新了啥?

本文深入解析2024年IPC-A-610J和J-STD-001J新标准的核心更新,重点关注电子制造领域的验收标准与工艺参数变化。新版标准强化了高密度组装和微焊接工艺的规范,包括焊料润湿角调整、BGA空洞率严格化等关键变更,为电子工程师提供实用指南。同时关联IPC-7711/21D和IPC-2221C的配套更新,助力企业快速适应新标准要求。

weixin_33694620的博客 780

(C#脚本)Unity中角色移动的几种实现方法,以及心得。(适合新手入门)

PS:首先我们要知道,在C#中Transform组件是可以直接调用的,而其他的(例如:Rigidbody,Animator)都需要通过 GetConpoment<组件的名称>(); 来获取进行实例化。 例子:调用Rigidbody2D private Rigidbody2D rb2D;//声明变量实例化 void Start() { rb2d = GetComponent<Rigidbody2D>();//获取 } 1.对Unity脚本写入有一定的思维了解...

qq_48860282的博客 1万+

034、特定场景优化(一):小目标检测的改进策略合集

本文针对工业场景中的小目标检测难题,提出了一套实战优化方案。首先从数据层面建议保持高分辨率输入(1024-1280像素)或采用切块训练策略,并适当放大标注区域。在网络结构上,提出减少下采样次数、增加高分辨率检测头、引入空间注意力机制等改进。损失函数方面推荐使用NWD匹配和QFL损失提升小目标敏感度。部署环节强调NMS优化、分辨率对齐和量化处理技巧。最后总结核心经验:优先优化数据质量而非模型结构,标注一致性比算法更重要,同时需为实际部署预留性能余量。硬件升级有时比算法调优更经济有效。

xiaoyaohou11的博客 652

ubuntu18.04安装Nvidia显卡驱动后黑屏及网络、蓝牙驱动消失的解决方案

ubuntu18.04安装Nvidia显卡驱动后黑屏及网络、蓝牙驱动消失的解决方案

weixin_40735291的博客 6618

CNN经典论文(一)LeNet

Gradient-Based Learning Applied to Document Recognition(梯度学习在文档识别中的应用) Yann LeCun, Leon Bottou, Yoshua Bengio, and Patrick Haffner 发表时间:December 1998 期刊:Proceedings of the IEEE 影响:世界上第一个卷积神经网络 论文地址:Gradient-Based Learning Applied to Document Recognition

loveling丶的博客 3597

Fluent求解器——湍流参数的设置

Fluent湍流参数的介绍和设置。

Ronko_G的博客 4万+

你分得清ChatGPT、Gemini、Grok、豆包、千问、DeepSeek、OpenClaw、CloudCode、vibeCodeing、sKill、MCP,飞书、微信这些到底是什么吗?

AI技术生态呈现层级化发展,从基础模型到应用平台形成完整技术栈。核心分为五层:模型层(GPT、Gemini等基础模型)→AI助手层(ChatGPT等应用产品)→工具层(ClaudeCode等开发工具)→协议层(MCP等接口标准)→应用层(微信、飞书等平台)。未来趋势将形成"模型公司-开发框架-应用生态"三层结构,AI正逐步演变为新型操作系统,通过标准化协议连接各类外部系统,实现能力调用与生态整合。技术发展呈现出从底层基础设施到上层应用场景的垂直整合特征。

hy行者勇哥的博客 397

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: Subscription (多卡管理) 架构设计
下一篇: PhoneFactory / Phone 启动流程架构设计
爆打葡萄汁
博客等级 码龄7年 30粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值