代码分析:
参与其中的总共八个对象,分别是Listview
,AbsListView
,ArrayAdapter
,BaseAdapter
,AdapterDataSetObserver
,DataSetObserver
,DataSetObservable
,Observable
四个抽象对象,四个实体对象。
- 首先,
DataSetObserver
定义了两个方法给子类继承,用于通知更改
public abstract class DataSetObserver {
public void onChanged() {}
public void onInvalidated() {}
}
- 然后
AdapterDataSetObserver
继承了这两个方法,在onChanged
的时候申请了重绘视图
class AdapterDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
...
requestLayout(); //这个是向系统申请重新绘制视图的方法
}
}
Listview
继承AbsListView
,我们在给它设置setAdapter
的时候,创建了AdapterDataSetObserver
@Override
public void setAdapter(ListAdapter adapter) {
...
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
...
}
同时,把这个AdapterDataSetObserver
注册到了mAdapter
里。
- 另一边,抽象类
Observable<T>
维护了一个ArrayList,用来存放观察者
public abstract class Observable<T> {
protected final ArrayList<T> mObservers = new ArrayList<T>();
public void registerObserver(T observer) {...}
public void unregisterObserver(T observer) {...}
}
DataSetObservable
继承Observable<DataSetObserver>
并指定了泛型类型为前面的DataSetObserver
抽象观察者
public void notifyChanged() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
public void notifyInvalidated() {
synchronized (mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onInvalidated();
}
}
}
- 在ArrayAdapter的父类
BaseAdapter
中创建了DataSetObservable
;
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
这样一来,ArrayAdapter 其实默认就拥有了四个方法,
registerDataSetObserver
unregisterDataSetObserver
notifyDataSetChanged
notifyDataSetInvalidated
现在都准备好了,
当我们创建Listview
后,就给它设置adapter
,这时,adapter
顺便把Listview
里的AdapterDataSetObserver
注册到了ArrayList<T> mObservers
观察者列表里。
当我们更新Listview
列表数据时,就要调用adapter
的notifyDataSetChanged
,这样就会去遍历所有ArrayList<T> mObservers
集合里的观察者,并调用他们的onChanged
,此时,Listview
里的AdapterDataSetObserver
就会调用onChanged
,从而申请Listview
重新绘制。这样Listview
就会刷新显示了。
代码看完了,现在假如我们自己要写个观察者模式怎么做?
1.新建抽象观察者,只写抽象方法,用来接收信号
public abstract class 抽象观察者{
public void 接收信号{};
}
2.新建具体观察者,重载方法,用来做具体收到信号后干什么
public class 实际观察者 extends 抽象观察者{
@Override
public void 接收信号{
宣告世界,我收到信号了.
}
}
3.新建抽象被观察者,保存一个List集合,用来存储所有观察者。
public abstract class 抽象被观察者<T> {
protected final ArrayList<T> mObservers = new ArrayList<T>();
public void 添加到集合(T observer) {...}
public void 从集合删除(T observer) {...}
}
4.新建具体被观察者,用来更新数据,通知他人。
public class 具体被观察者<泛型指定抽象观察者> {
public void 通知所有人() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).接收信号();
}
}
}
5.基本四个类已经写好了,剩下的就是注册和使用了。
先写服务端,用来注册和通知。
public class 服务端{
//新建一个具体被观察者
new 具体被观察者
//提供方法用来把观察者添加和删除被观察者的集合里
public void 添加观察者{
具体观察者.添加到集合();
}
...
}
新建客户端,用来接收通知。
public class 客户端 {
//新建一个观察者
new 实际观察者
//获取
设置服务端
//调用服务端的添加删除方法,把这里的实际观察者放到服务端那边
服务端.添加观察者
//现在一切都设置好了。
//当服务端有了新通知的时候
具体的,比如网络那边有新消息发给你了
这时候服务端就会调用具体的被观察者去发送通知
然后客户端这里的观察者就会收到通知。
}
实际上总共就四个对象。
A
想接收信号类B
想发送信号的类C
可以观察接收信号的类D
可以发送信号的类
然后ABCD都可以做抽象继承,这样就会有8个类了,简单点写就是4个类了。
操作过程:
- 新建的时候,
A里面新建C 持有B,B里面新建D ,A让B把C放到D的列表里
。 - 更新的时候,
B让D,向D的列表里所有的C发送信号,这时候A里面的C就会接收到信号
。
总结:
实际上就是搞清楚一下几点。
- 谁想接收信号
就新建一个观察者,添加到集合里
- 谁想发送信号
就新建一个被观察者,提供方法来添加和删除,以及通知消息
- 谁可以发出信号
就用一个集合来存储那些观察者,并提供方法遍历集合发送消息
- 谁可以接收信号
就用来接收消息,做你想做的事