代碼分析:
參與其中的總共八個對象,分別是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就會接收到信號
。
總結:
實際上就是搞清楚一下幾點。
- 誰想接收信號
就新建一個觀察者,添加到集合裏
- 誰想發送信號
就新建一個被觀察者,提供方法來添加和刪除,以及通知消息
- 誰可以發出信號
就用一個集合來存儲那些觀察者,並提供方法遍歷集合發送消息
- 誰可以接收信號
就用來接收消息,做你想做的事