Registrant/RegistrantList

38 阅读3分钟

RegistrantList的原理

在Telephony模块中,在RIL、Tracker(ServiceStateTracker、CallTracker、DcTracker)、Phone、UICC框架、CallManager等等中都大量使用到的RegistrantList

观察者模式:定义对象间的一种一(Subject)对多(Observer)的依赖关系,当一个对象的状态改变时,所有依赖于它的对象都得到通知并且自动更新。

RegistrantList跟观察者模式有点类似,先创建一个RegistrantList集合,专门关注某种消息;若有人也对该消息感兴趣的话,那么为他封装一个Registrant对象并且添加到RegistrantList中;当有消息上报时,先通知RegistrantList,接着所有注册到RegistrantList中的Registrant都会被通知到并且更新。

Registrantlist使用的观察者模式中,Registrantlist为通知者,Registrant为观察者。这是一个一对多的关系,在有事件更新时,凡是在名单上登记过的对象,都会收到通知。

处理逻辑

包含方法

本质

Registrantlist

通知者

负责对通知者的增加(add/addUnique)、删除(remove),并且能够发出通知(notifyRegistrants)

通知者发起对所有观察者的通知

add()/addUnique():增加一个Registrant

remove():删除一个Registrant

internalNotifyRegistrants():通知所有的Registrant

Registrant的集合

Registrant

观察者

由其internalNotifyRegistrants方法负责响应通知者发出的notifyRegistrants 通知

观察者对对象列表的管理,对其进行注册和取消

internalNotifyRegistrant():在收到RegistrantList的通知之后,再更新自己的内容

handle和message的组合体

整体上这个消息注册机制分为2部分,消息注册和消息通知。其总体思想是:一个对象中开辟一个空间用于存放Message,当调用regist方法时将Message存放进去,当其调用notify方法时将所有Message取出并发送到MessageQueue中等待处理。

RegistrantList与Registrant的关系

运用

选DcTracker.java中监听数据开关状态变化作为例子分析一下

整个RegistrantList注册Registrant,再到通知Registrant这个过程,也是利用了回调,上层向下层注册回调(将handler传过去),当下层处理完后,调用回调接口通知上层结果。

回调过程:DcTracker对DataEnabledSettings说,你帮我留意一下通话数据开关状态变化这个消息啊!

DataEnabledSettings说,什么时候有通话挂断消息来我也不清楚啊,要不你留个联系方式给我?

DcTracker就传递了Handler和消息类型给DataEnabledSettings,然后自己就去忙其他事了。

DataEnabledSettings通过RegistrantList,把DcTracker的联系方式传递给了Registrant。

等到通话挂断消息上报时,RegistrantList先通知Registrant,然后Registrant就给DcTracker发消息。

第一步:创建一个RegistrantList,只关注某种消息

new 一个 RegistrantList 对象, 会在RegistrantList类里会自动new一个ArrayList,用来保存所有加入的单个Registrant

RegistrantList mEregrtIndRegistrants = new RegistrantList();

第二步、注册监听某个消息,将Registrant加到RegistrantList中

    public void registerForEregrtInd(Handler h, int what, Object obj) {
        Registrant r = new Registrant(h, what, obj);
        mEregrtIndRegistrants.add(r);
    }

第三步、发送通知,notify

当收到监听的那个消息后,先通知RegistrantList

    public void eregrtInfoInd(int indicationType, ArrayList<Integer>  info) {
        mRil.processIndication(indicationType);
        if (ImsRILAdapter.IMS_RILA_LOGD) {
            StringBuilder b = new StringBuilder();
            b.append("eregrtInfoInd: ");
            for (Integer i : info) {
                b.append(i).append(", ");
            }
            b.deleteCharAt(b.length()-1);
            mRil.riljLog(b.toString());
        }
        if (mRil.mEregrtIndRegistrants != null) {
            mRil.mEregrtIndRegistrants.notifyRegistrants(
                    new AsyncResult(null, info, null));
        }
    }

在RegistrantList的内部:

    notifyRegistrants(AsyncResult ar)
    {
        internalNotifyRegistrants(ar.result, ar.exception);
    }

    private synchronized void
    internalNotifyRegistrants (Object result, Throwable exception)
    {
       //遍历registrants列表
       for (int i = 0, s = registrants.size(); i < s ; i++) {
            Registrant  r = (Registrant) registrants.get(i);
            //通知registrant
            r.internalNotifyRegistrant(result, exception);
       }
    }

来到Registrant里:

    internalNotifyRegistrant (Object result, Throwable exception)
    {
        //获得handler对象
        Handler h = getHandler();


        if (h == null) {
            clear();
        } else {
            Message msg = Message.obtain();


            msg.what = what;
            msg.obj = new AsyncResult(userObj, result, exception);
            //通过回调,给handler发message
            h.sendMessage(msg);
        }
    }