观测者模式介绍:
常用于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消息处理处,就可以找到这个消息通知的地方了。