description: “SignalStrength 信号强度架构设计——Android 信号格的算数引擎,涵盖 SignalStrength 多 RAT 容器模型、CellSignalStrength 系列类层次、getLevel() 5 级离散化算法、getPrimary() 主 RAT 优先级选择、SignalThresholdInfo 阈值上报机制。”
SignalStrength 是 Android 中负责信号强度测量和量化的核心类。它将 Modem 上报的原始信号物理量(dBm、RSRP、RSSI、SNR 等)转换为用户看得懂的 5 级信号格(0~4 格),同时支持按阈值主动上报——当信号突破特定阈值时才通知上层,避免频繁的 UI 刷新。
在 Multi-RAT 时代,设备可能同时连接 LTE 和 NR (NSA 架构),SignalStrength 需要智能判断"当前以哪个 RAT 的信号强度为准"来更新信号格图标。
设计理念: SignalStrength 的设计核心是"多 RAT 容器 + 主 RAT 决策"。不同无线接入技术测量信号的方式完全不同(GSM 用 RSSI,LTE 用 RSRP,NR 用 SS-RSRP),
SignalStrength将它们统一抽象为CellSignalStrength*系列,然后通过getPrimary()选择最相关的 RAT 作为当前信号强度来源。
1. 核心职责
- 多 RAT 信号存储:同时保存 GSM/WCDMA/TDSCDMA/CDMA/LTE/NR 六种 RAT 的信号强度
- 信号级离散化 (getLevel):将原始 dBm 值映射为 0-4 的五级信号格
- 主 RAT 确定 (getPrimary):决定当前以哪个 RAT 的信号强度为准
- 阈值上报:通过
SignalThresholdInfo实现"只有突破阈值才通知"的高效机制 - 兼容性:支持旧 API (
getGsmSignalStrength(),getCdmaDbm()等) 并桥接到新 API
2. 核心类与源码锚点
- [SignalStrength.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/SignalStrength.java):顶层容器,持有 6 个 RAT 的
CellSignalStrength*实例。 - [CellSignalStrength.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/CellSignalStrength.java):抽象基类,定义
getLevel()、getDbm()、getAsuLevel()等公共接口。 - [CellSignalStrengthLte.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/CellSignalStrengthLte.java):LTE 信号强度实现。使用 RSRP/RSSI/RSRQ/SINR。
- [CellSignalStrengthNr.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/CellSignalStrengthNr.java):NR (5G) 信号强度实现。使用 SS-RSRP/SS-RSRQ/SS-SINR/CSI-RSRP 等。
- [CellSignalStrengthGsm.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/CellSignalStrengthGsm.java):GSM 信号强度实现。使用 RSSI/BER。
- [CellSignalStrengthWcdma.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/CellSignalStrengthWcdma.java):WCDMA 信号强度实现。
- [CellSignalStrengthCdma.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/CellSignalStrengthCdma.java):CDMA 信号强度实现。同时包含 CDMA 1x 和 EVDO 两种信号。
- [CellSignalStrengthTdscdma.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/CellSignalStrengthTdscdma.java):TDSCDMA 信号强度实现。
- [SignalThresholdInfo.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/telephony/java/android/telephony/SignalThresholdInfo.java):阈值上报配置。
3. Google 设计技巧深入分析
3.1 多 RAT 容器模型 — 一次性更新所有信号
public class SignalStrength implements Parcelable {
CellSignalStrengthCdma mCdma;
CellSignalStrengthGsm mGsm;
CellSignalStrengthWcdma mWcdma;
CellSignalStrengthTdscdma mTdscdma;
CellSignalStrengthLte mLte;
CellSignalStrengthNr mNr;
}
Google设计技巧 #1 — "全量更新"信号容器:
每次信号强度变化时,所有 6 个CellSignalStrength*实例都通过一个SignalStrength对象一起传递。这不是浪费——在多 RAT 连接场景(如 LTE+NR NSA),系统需要同时知道两个 RAT 的信号强度。即使某个 RAT 当前不可用,它也通过isValid()返回false表示"无有效信号",而不是null。
3.2 getPrimary() — 主 RAT 优先级选择
private CellSignalStrength getPrimary() {
// 优先级:NR > LTE > WCDMA > TDSCDMA > CDMA > GSM
if (mNr.isValid()) return mNr;
if (mLte.isValid()) return mLte;
if (mWcdma.isValid()) return mWcdma;
if (mTdscdma.isValid()) return mTdscdma;
if (mCdma.isValid()) return mCdma;
if (mGsm.isValid()) return mGsm;
return mLte; // 默认回退
}
Google设计技巧 #2 — 主 RAT 优先级策略:
信号格显示遵循"最新最强"原则——NR (5G) 优先级最高,GSM 最低。这是因为:
- NR 能提供最大的带宽,信号强度的用户体验最相关
- 在 NSA (Non-Standalone) 架构中,UE 同时连接 LTE (锚点) 和 NR (数据增强),NR 的信号强度更能反映实际体验
mLteAsPrimaryInNrNsa标志位允许 OEM 配置在 NR NSA 场景下仍以 LTE 信号为主
3.3 getLevel() — 5 级离散化算法
public int getLevel() {
CellSignalStrength primary = getPrimary();
int level = primary.getLevel();
if (level < 0 || level > 4) level = 0;
// 在 LTE 作为 NR NSA 锚点时特殊处理
return level;
}
每个 RAT 的 getLevel() 使用不同的阈值表:
| 信号级 | GSM (asu) | LTE (dBm RSRP) | NR (dBm SS-RSRP) |
|---|---|---|---|
| 0 (NONE) | 0 | ≤ -140 | ≤ -140 |
| 1 (POOR) | 1-2 | -139 ~ -128 | -139 ~ -128 |
| 2 (MODERATE) | 3-6 | -127 ~ -118 | -127 ~ -118 |
| 3 (GOOD) | 7-15 | -117 ~ -108 | -117 ~ -108 |
| 4 (GREAT) | ≥ 16 | ≥ -107 | ≥ -107 |
Google设计技巧 #3 — 各 RAT 独立定义阈值表:
不同 RAT 的信号测量物理意义完全不同(GSM 的 RSSI vs LTE 的 RSRP vs NR 的 SS-RSRP),因此每个CellSignalStrength*子类都在自己的getLevel()中定义独立的阈值表。这避免了"一刀切"带来的不准确性。例如,LTE 的 RSRP -110 dBm 可能是GOOD,但 NR 的 SS-RSRP -110 dBm 在 NSA 架构下可能需要重新评估。
3.4 CellSignalStrength — 模板方法模式
public abstract class CellSignalStrength {
public abstract int getLevel();
public abstract int getDbm();
public abstract int getAsuLevel();
public abstract void setDefaultValues();
// 通用常量
public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
public static final int SIGNAL_STRENGTH_POOR = 1;
public static final int SIGNAL_STRENGTH_MODERATE = 2;
public static final int SIGNAL_STRENGTH_GOOD = 3;
public static final int SIGNAL_STRENGTH_GREAT = 4;
}
Google设计技巧 #4 — 抽象基类的模板方法 + 统一常量:
CellSignalStrength定义抽象方法getLevel()和getDbm(),6 个子类各自实现。但信号强度的 5 级常量(0-4)在基类中统一定义,确保所有 RAT 使用相同的级别系统——App 层看来无论设备接的是 5G 还是 2G,信号格的含义是一致的。
3.5 SignalThresholdInfo — 阈值上报
public class SignalThresholdInfo {
// RAN 层级定义阈值,只有穿越阈值时才通知上层
// 避免每
3576



被折叠的 条评论
为什么被折叠?



