在android应用里面要取得并处理一条消息,是比较漫长和复杂的。首先要取得消息,必须先注册该消息,并且提供响应的handler。比如一条新来电的消息,PHONE_NEW_RINGING_CONNECTIO,这条消息是
由CallNotifier定义并注册的,当有新来电时候,CallNotifier.handleMessage()就会得到并判断该消息类型,然后调用onNewRingingConnection((AsyncResult) msg.obj)进行响应的处理。问题来了,
CallNotifier怎么就能够拿到这条消息呢?
一、CallNotifier首先定义了该消息的ID :private static final int PHONE_NEW_RINGING_CONNECTION = 2;
二、CallNotifier像GSMPhone注册该条消息,mPhone.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null);注册消息的时候,必须提供handle(即CallNotifier自己,因为它是继承Handle类)和消息ID(PHONE_NEW_RINGING_CONNECTION, 表示该消息唯一)。
三、mPhone 是GSMPhone 的对象,GSMPhone是抽象类PhoneBase的子类(PhoneBase还是CDMAPhone的父类,里面定义了一些抽象的事件和CDMA GSM共有的操作)。registerForNewRingConnection()是PhoneBase类的方法
public void registerForNewRingingConnection(Handler h, int what, Object obj)
{
checkCorrectThread(h);
mNewRingingConnectionRegistrants.addUnique(h, what, obj);
}
checkCorrectThred(h)检查Handler的Looper是否当前Looper,即当前线程跟Handler所属的线程是否相同,不是则抛出异常
然后就是添加一个唯一的消息和handler了。mNewRingConnectionRegistrants是注册列表RegistrantList的对象,将新号添加到信号链表里面去,这样就完全把一个信号给注册完成了。
四、在注册PHONE_NEW_RINGING_CONNECTION之前,必须从CallNotifier对象上次注册的对应的信号从信号链表中删除掉,通过在CallNotifier中调用PhoneBase.unregisterNewRingingConnection()方法。
五、CallNotifier接收到该信号的时候,调用onNewRingingConnection((syncResult)msg.obj), 可是参数msg.obj在注册信号的时候是空的。在PhoneBase内,有方法:
protected void notifyNewRingingConnectionP(Connection cn)
{
AsyncResult ar = new AsyncResult(null, cn, null);
mNewRingingConnectionRegistrants.notifyRegistrants(ar);
}
该方法就是为当前来电指定一个新连接,所以,msg.obj就指定了一个Connection对象,然后就告知所有的消息队列,这样,注册消息的Handler就能拿到这个消息了