观察者模式与RegistrantList机制

观测者模式介绍:
常用于GUI系统,订阅发布系统。其主要作用就是解耦。将观察者和被观察者解耦。
观察者模式定义:
定义对象间一对多的关系,每当一个对象改变时所有依赖于它的对象都会得到通知并自动更新。

简单实现:
1.主题拥有一个观察者的对象集合
2.有注册去注册方法和更新方法,其中更新方法会调用观察者对象自身的update方法
3.观察者接口拥有update方法,其子类具体实现了更新方法

具体代码:

定一个主题,拥有一个观察者的对象集合,注册去注册方法和更新方法
public interface Subject {
        ArrayList<Obeseve> obList = new ArrayList<Obeseve>();
        void registerSub(Obeseve o);
        void unRegisterSub(Obeseve o);
        void notifysAll();
}
//观察者
public interface Obeseve {
        void update();
}
//具体主题
package observe;

public class ConSubject implements Subject{

        public ConSubject() {
                // TODO Auto-generated constructor stub

        }

        @Override
        public void registerSub(Obeseve o) {
                // TODO Auto-generated method stub
                obList.add(o);
        }

        @Override
        public void unRegisterSub(Obeseve o) {
                // TODO Auto-generated method stub
                obList.remove(o);
        }

        @Override
        public void notifysAll() {
                // TODO Auto-generated method stub
                for(int i=0;i<obList.size();i++){
                        obList.get(i).update();
                }
        }

}
//具体观察者
package observe;

public class ConObseve implements Obeseve{

        @Override
        public void update() {
                // TODO Auto-generated method stub
                System.out.println("收到消息了");
        }

}
//测试
package observe;

public class test {
        public static void main(String[] args) {
                Subject sub = new ConSubject();
                Obeseve ob = new ConObseve();
                sub.registerSub(ob);
                sub.notifysAll();
        }
}

在Android源码中我们可以经常看到RegistrantList的身影,其本质也是和Registrant一起构成观察者模式,利用注册时的hander实例,用来在系统间通知消息。
我们先看下Registrant类的结构

    public
    Registrant(Handler h, int what, Object obj)
    {
        refH = new WeakReference(h);
        this.what = what;
        userObj = obj;
    }

可以看到Registrant的构造函数中初始化了一个弱引用的hander实例,接着我们继续看看Registrant的update方法

    public void
    notifyRegistrant()
    {
        internalNotifyRegistrant (null, null);
    }

    public void
    notifyResult(Object result)
    {
        internalNotifyRegistrant (result, null);
    }
继续跟进internalNotifyRegistrant
    /*package*/ void
    internalNotifyRegistrant (Object result, Throwable exception)
    {
        Handler h = getHandler();

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

            msg.what = what;

            msg.obj = new AsyncResult(userObj, result, exception);

            h.sendMessage(msg);
        }
    }

利用初始化的hander实例进行发送消息。
继续看下RegistrantList.java

//存放注册的观察者
 ArrayList   registrants = new ArrayList();      // of Registrant

通知观察者
    private synchronized void
    internalNotifyRegistrants (Object result, Throwable exception)
    {
       for (int i = 0, s = registrants.size(); i < s ; i++) {
            Registrant  r = (Registrant) registrants.get(i);
            r.internalNotifyRegistrant(result, exception);
       }
    }

这样我们就可以再注册某个事件后,在自身的handleMessage中等待该消息的通知,再做进一步处理。
在来电分析的博客中我们有看到这样的通知

mRil.mCallStateRegistrants.notifyRegistrants();

那么我们如何追踪此消息被通知到何处呢?
具体思路如下:
1.查找RegistrantList对象注册观察者Registrant对象的方法,通常为registerForXXX方法,此方法调用RegistrantList的add方法,也就是注册方法
2.查找该方法的调用方,关注其形参,通常传入的是this或者,mHander即消息 的接收处理类。
3.根据传入的hander实例找到对应的handeMessage消息处理处,就可以找到这个消息通知的地方了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值