关于Handler二三事(下)
从接触呼叫业务的第一天起,我就一直琢磨代码里成群结队的registerXXXX方法跟notifyXXXX方法究竟是个怎么关系。
一个消息(Message)从注册到被处理(handleMessage)都经过了哪些步骤?为什么要通过这种设计来完成线程间通信?是什么决定哪些消息在哪些类中被处理?消息上报之后,framework层都完成了哪些工作?
诸如此类,一言难尽。
在过去的总结中,我倾向于通过业务层不同呼叫状态的实例含义来理解整个通话的过程,而不是专注于dial,hangup,rejectCall,acceptCall这类的具体通话流程。换句话说,我觉得,如果能掌握不断改变的通话状态与android系统所做的处理之间的联系,也就能明白呼叫业务、甚至是android通信流程的真正脉络。
而这个Register-Notify模型,恐怕就是理解它的钥匙之一。
当我们正在谈论注册(register)的时候,它们在干什么
所谓的registerXXX,简单的说就是在某个特定的泛型列表中添加一个新的泛型节点。
两个有趣的地方。
第一, 为什么要通过不同的泛型列表来搜集不同的消息?
第二, 添加的这个新的泛型节点都包括哪些内容?
首先来看第二个问题,一个新的泛型节点通常包含了以下三样东西:
Handler h, int what, Object obj
在一个注册方法被调用时,h代表了能处理这个消息,同时也继承了Hanlder类的线程名称,what代表了该消息标签名称,而obj代表了以基本对象为格式所封装的消息内容。
再来看一个新的Registrant泛型节点用这些参数都构成了什么。
当然,这只是个诸多消息回调中比较典型的一种罢了。
最后再补一句。
在android framework层并非所有的消息都是通过Handler回调机制来完成的。譬如跟RIL层接口的ril.java文件,尽管也用到了obtain和send方法来实现消息的产生与投递,但事实上它的收发机制是socket套接字的方式与RILD进行数据交互,所以对它的消息收发仍需要仔细研究代码才可以。