Telephony 线程模型 — AsyncResult / RegistrantList / HandlerThread

1. 概述

Android Telephony 框架是全异步 + 多线程架构的典范。由于 RIL 层通信本质上是异步的(AT 命令 → Modem → 等待响应),Google 设计了一套贯穿全框架的异步消息传递基础设施AsyncResult(异步结果载体)、RegistrantList(观察者列表)、Registrant(弱引用观察者)。这三个类虽不超过 300 行代码,却是整个 Telephony 框架几十万行代码的"血管系统"——所有 RIL 回调、状态变更通知、跨层消息都通过它们流转。

1.1 核心概念

概念 含义
AsyncResult 异步操作的结果包装器,封装 result(成功数据)、exception(失败异常)、userObj(用户自定义上下文)
RegistrantList 观察者列表容器,维护多个 Registrant 对象的集合,用于一对多的事件通知
Registrant 单个事件订阅者,持有目标 HandlerWeakReference + what + userObj
HandlerThread 专用消息线程,Android 提供的基础设施。Telephony 中大量用于隔离耗时操作
Message.what Android Handler 消息类型标识(int),Telephony 中通过 EVENT_* 常量定义

1.2 为什么不用传统观察者模式

// 传统观察者模式 (Java Observer)
public interface OnServiceStateChangedListener {
   
   
    void onServiceStateChanged(ServiceState ss);
}
// → 需要强引用、需要判空、需要 unregister 时遍历...

// Telephony 的 RegistrantList 模式
RegistrantList mServiceStateRegistrants = new RegistrantList();
mServiceStateRegistrants.notifyResult(serviceState);
// → WeakReference 自动防泄漏、无需显式 unregister、内置异常路径通知

Google 设计技巧 #1 — WeakReference 防泄漏 + 零开销清理
Registrant 持有 WeakReference<Handler>,当 Handler 所在的线程或对象被 GC 回收后,RegistrantList 在下一次 notify 时通过 removeCleared() 自动清理失效的 Registrant。这意味着注册者不需要显式调用 unregister(),框架不会因为忘记取消注册而产生内存泄漏。


2. 核心类与源码锚点

类名 路径 说明
AsyncResult [AsyncResult.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/core/java/android/os/AsyncResult.java) 异步结果容器 (74 行代码)
RegistrantList [RegistrantList.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/core/java/android/os/RegistrantList.java) 观察者列表容器
Registrant [Registrant.java](file:///d:/Resource%20Android%2016/android-16/frameworks/base/core/java/android/os/Registrant.java) 单个事件注册者
HandlerThread android.os.HandlerThread (framework) 专用消息线程
CommandsInterface frameworks/opt/telephony/src/java/.../CommandsInterface.java RIL 回调接口定义
ServiceStateTracker frameworks/opt/telephony/src/java/.../ServiceStateTracker.java 典型的 RegistrantList 使用者

3. AsyncResult 详解 — 异步铁三角

3.1 极简结构

// AsyncResult.java
public class AsyncResult {
   
   
    public Object userObj;       // 用户自定义上下文 (调用时传入)
    public Throwable exception;  // 异常 (成功时为 null)
    public Object result;        // 结果 (异常时为 null)

    /** 工厂方法:构造 AsyncResult 并挂载到 Message.obj */
    public static AsyncResult forMessage(Message m, Object r, Throwable ex) {
   
   
        AsyncResult ret = new AsyncResult(m.obj, r, ex);
        m.obj = ret;
        return ret;
    }
}

3.2 三个字段的语义规则

场景 exception result 含义
操作成功 null 实际数据 一切正常,result 是返回值
操作失败 CommandException null RIL 层错误
操作失败 ImsException null IMS 层错误

Google 设计技巧 #2 — “要么 result 要么 exception,两者互斥”
AsyncResult 不引入复杂的 Success<T>/Failure<E> 代数类型。它只用两个可 null 的 Object 字段表达"成功或失败"——exception != null 就是失败路径,result != null 就是成功路径。上层代码通过一个 if 判断分流:

AsyncResult ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
    
    
    handleError((CommandException) ar.exception);
} else {
    
    
    handleResult((YourDataType) ar.result);
}

这比 Java 的 try-catch 模式更高效(无异常栈开销),也比 Kotlin 的 Result 更简洁(兼容 Java 老代码)。


4. RegistrantList 详解 — 弱引用观察者集合

4.1 核心方法

// RegistrantList.java
public class RegistrantList {
   
   
    ArrayList registrants = new ArrayList();  // of Registrant

    /** 注册观察者 */
    public synchronized void add(Handler h, int what, Object obj) {
   
   
        add(new Registrant(h, what, obj));
    }

    /** 去重注册 (同一个 Handler 只保留最后一次) */
    public synchronized void addUnique(Handler h, int what, Object obj) {
   
   
        remove(h);  // 先移除旧的
        add(new Registrant(h, what, obj));  // 再添加新的
    }

    /** 自动清除已失效的 Registrant (GC 回收的) */
    public synchronized void removeCleared() {
   
   
        for (int i = registrants.size() - 1; i >= 0; i--) {
   
   
            Registrant r = (Registrant) registrants.get(i);
            if (r.refH == null) {
   
   
                registrants.remove(i);
            }
        }
    }

    /** 通知所有观察者:成功(带 result) */
    public synchronized void notifyResult(Object result) {
   
   
        for (int i = 0, s = registrants.size(); i < s; i++) {
   
   
            Registrant r = (Registrant) registrants.get(i);
            r.notifyResult(result);
        }
    }

    /** 通知所有观察者:异常(带 exception) */
    public synchronized void notifyException(Throwable exception) {
   
   
        for (int i = 0, s = registrants.size(); i < s; i++) {
   
   
            Registrant r = (Registrant) registrants.get(i);
            r.notifyException(exception);
        }
    }

    /** 通知所有观察者:直接从 AsyncResult 拷贝 */
    public synchronized void notifyRegistrant(AsyncResult ar) {
   
   
        for (int i = 0, s = registrants.size(); i < s; i++) {
   
   
            Registrant r = (Registrant) registrants.get(i);
            r.notifyRegistrant(ar);
        }
    }
}

4.2 RegistrantList 的使用模式

// ServiceStateTracker.java — 典型的 RegistrantList 定义和使用
public class ServiceStateTracker extends Handler {
   
   
    // 定义:支持多个订阅者同时监听服务状态变化
    private RegistrantList mServiceStateRegistrants = new RegistrantList();
    private RegistrantList mCellInfoRegistrants = new RegistrantList();
    private RegistrantList mSignalStrengthRegistrants = new RegistrantList();
    // ...

    // 注册:被其他组件调用
    public void registerForServiceStateChanged(Handler h, int what, Object obj) {
   
   
        mServiceStateRegistrants.addUnique(h, what, obj);
    }

    // 通知:当服务状态变化时
    private void notifyServiceStateChanged(ServiceState ss) {
   
   
        mServiceStateRegistrants.notifyResult(ss);
    }
}

4.3 典型的多方注册场景

三方 App TelephonyRegistry GsmCdmaPhone RegistrantList ServiceStateTracker 三方 App TelephonyRegistry GsmCdmaPhone RegistrantList ServiceStateTracker
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值