java.util.Observable中有兩個方法對Observer特別重要
①setChanged()方法
/** * Sets the changed flag for this {@code Observable}. After calling * {@code setChanged()}, {@code hasChanged()} will return {@code true}. */ protected void setChanged() { changed = true; }
②notifyObservers()方法 / notifyObservers(Object data)方法
/** * If {@code hasChanged()} returns {@code true}, calls the {@code update()} * method for every observer in the list of observers using null as the * argument. Afterwards, calls {@code clearChanged()}. * <p> * Equivalent to calling {@code notifyObservers(null)}. */ public void notifyObservers() { notifyObservers(null); } /** * If {@code hasChanged()} returns {@code true}, calls the {@code update()} * method for every Observer in the list of observers using the specified * argument. Afterwards calls {@code clearChanged()}. * * @param data * the argument passed to {@code update()}. */ @SuppressWarnings("unchecked") public void notifyObservers(Object data) { int size = 0; Observer[] arrays = null; synchronized (this) { if (hasChanged()) { clearChanged(); size = observers.size(); arrays = new Observer[size]; observers.toArray(arrays); } } if (arrays != null) { for (Observer observer : arrays) { observer.update(this, data); } } }
以上兩個方法十分重要
setChanged()方法
——
用來設定一個內部標誌位註明資料發生了變化
notifyObservers()方法
/ notifyObservers(Object data)方法 ——
通知所有的Observer資料發生了變化,這時所有的Observer會自動調用複寫好的update(Observable
observable, Object data)方法來做一些處理(比如說畫面資料的更新)。
我們可以看到通知Observer有兩個方法,一個無參,一個有參。那麼這個參數有什麼作用呢?
其中一個作用:現在我不想通知所有的Observer,而只想其中一個指定的Observer做一些處理,那麼就可以傳一個參數作為ID,然後在所有的Observer中判斷,每個Observer判斷只有接收到底參數ID是屬於自己的才做一些處理。
當然參數還有其他作用,我只是舉了個例子。
下面舉個例子加以說明:
import java.util.Observable; /** * 被觀察者類 */ public class SimpleObservable extends Observable { private int data = 0; public int getData(){ return data; } public void setData(int i){ if(this.data != i) { this.data = i; setChanged(); //只有在setChange()被調用後,notifyObservers()才會去調用update(),否則什麼都不幹。 notifyObservers(); } } }
上面這個類是一個被觀察者類,它繼承了Observable類,表示這個類是可以被觀察的。
然後在setData()方法裡面,也就是資料改變的地方,來調用Observable類的setChanged()方法和notifyObservers()方法,表示資料已改變並通知所有的Observer調用它們的update()方法做一些處理。
注意:只有在setChange()被調用後,notifyObservers()才會去調用update(),否則什麼都不幹。
/** * 觀察者類 */ public class SimpleObserver implements Observer { public SimpleObserver(SimpleObservable simpleObservable){ simpleObservable.addObserver(this ); } public void update(Observable observable ,Object data){ // data為任意對象,用於傳遞參數 System.out.println(“Data has changed to” + (SimpleObservable)observable.getData()); } }
通過產生被觀察者(SimpleObservable類)的執行個體,來調用addObserver(this)方法讓觀察者(SimpleObserver類)達到觀察被觀察者(SimpleObservable類)的目的。
然後還要複寫update()方法,做資料改變後的一些處理。
下面可以寫一個簡單的測試類別來測試一下
public class SimpleTest { public static void main(String[] args){ SimpleObservable doc = new SimpleObservable (); SimpleObserver view = new SimpleObserver (doc); doc.setData(1); doc.setData(2); doc.setData(2); doc.setData(3); } }
運行結果如下
Data has changed to 1 Data has changed to 2 //第二次setData(2)時由於沒有setChange,所以update沒被調用Data has changed to 3
下面介紹一個Observable類的其他一些屬性和方法
屬性 ——
// observers是一個List,儲存著所有要通知的observer。 List<Observer> observers = new ArrayList<Observer>();// changed是一個boolean型標誌位,標誌著資料是否改變了。boolean changed = false;
方法 ——
// 添加一個Observer到列表observers中public void addObserver(Observer observer) { if (observer == null) { throw new NullPointerException(); } synchronized (this) { if (!observers.contains(observer)) observers.add(observer); }}// 從列表observers中刪除一個observerpublic synchronized void deleteObserver(Observer observer) { observers.remove(observer);}// 清空列表observerspublic synchronized void deleteObservers() { observers.clear();}// 返回列表observers中observer的個數public int countObservers() { return observers.size();}// 重設資料改變標誌位為未改變protected void clearChanged() { changed = false;}// 將資料改變標誌位設定為改變protected void setChanged() { changed = true;}// 判斷標誌位的值public boolean hasChanged() { return changed;}// 通知所有observer(無參)public void notifyObservers() { notifyObservers(null);}// 通知所有observer(有參)@SuppressWarnings("unchecked")public void notifyObservers(Object data) { int size = 0; Observer[] arrays = null; synchronized (this) { if (hasChanged()) { clearChanged(); size = observers.size(); arrays = new Observer[size]; observers.toArray(arrays); } } if (arrays != null) { for (Observer observer : arrays) { observer.update(this, data); } }}
注意:在Observer對象銷毀前一定要用deleteObserver將其從列表中刪除,也就是在onDestroy()方法中調用deleteObserver()方法。
不然因為還存在對象引用的關係,Observer對象不會被垃圾收集,造成記憶體流失,並且已死的Observer仍會被通知到,有可能造成意料外的錯誤,而且隨著列表越來越大,notifyObservers操作也會越來越慢。
下面2個工程是Observable與Observer的經典運用,是android實現的單指拖動放大圖片的操作
兩個例子:
http://download.csdn.net/detail/tianjf0514/4237628
http://download.csdn.net/download/tianjf0514/4237634