2015年7月1日 星期三

[Android] Observer與Observable的相關知識

假如你對Observer與Observable還不太熟悉的話,可以先參考我的上一篇文章

Observer與Observable的基本用法

當你的類別實作Observer時,應該會有一個update的方法可以使用。

當Observable,setChanged及notifyObservers時就會去呼叫update這個方法。

我們看一下update這個方法會發現它會回傳兩個值給我們使用。

@Override
public void update(Observable observable, Object o) {
}
view raw gistfile1.java hosted with ❤ by GitHub
前者是Observable,也就是被觀察的對象,因為一個觀察者可以觀察很多被觀察者。

所以可以在這邊做判斷,看看到底是哪一個被觀察者發出訊息。

利用instanceof來判斷這個物件是哪個類別的實體。

@Override
public void update(Observable observable, Object o) {
if(observable instanceof MyObservable){
Log.d("tag" , "MyObservable");
}else if(observable instanceof MyObservable2){
Log.d("tag" , "MyObservable2");
}
}
view raw gistfile1.java hosted with ❤ by GitHub
後者是一個物件,這個更容易理解,你可以在notifyObservers的時候傳送一個物件給他,

就可以在這邊收到那個物件。

發送
String string = "哈囉";
notifyObservers(string);
//發送給觀察者
view raw gistfile1.java hosted with ❤ by GitHub

收到
@Override
public void update(Observable observable, Object o) {
String string = (String) o;
Log.d("tag" , string);
}
view raw gistfile1.java hosted with ❤ by GitHub
另外一個重點,當你結束這個頁面後,要記得刪除這個觀察者。

也就是使用deleteObserver方法來達成。

在Activity的話,可以寫在onDestroy裡面,就像以下的程式碼。

@Override
protected void onDestroy() {
super.onDestroy();
MyObservable.getInstance().deleteObserver(this);
}
view raw gistfile1.java hosted with ❤ by GitHub
這算是滿重要的觀念之一,若是不刪除的話可能會發生很可怕的事情,有多可怕,可以看一下這個實驗。

我們有兩個Activity,在onCreate的時候加入被觀察者,然後不刪除,看看會發生什麼事情,然後重複切換兩個頁面,當換頁的時候finish上一頁。

Observable有一個方法是可以看到現在有多少觀察者。

切換頁面然後finish,那應該只有一個觀察者存在,上一個都finish掉了,實際程式碼像這樣。

這是第一頁的程式碼

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyObservable.getInstance().addObserver(this);
//加入觀察者
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("tag", String.valueOf(MyObservable.getInstance().countObservers()));
//看一下這個被觀察者 有幾個觀察者在觀察
Intent intent = new Intent(MainActivity.this , MainActivity2Activity.class);
startActivity(intent);
//換到下一頁
finish();
//關閉這頁
}
});
}
view raw gistfile1.java hosted with ❤ by GitHub


這是第二頁的程式碼
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity2);
MyObservable.getInstance().addObserver(this);
//加入觀察者
button = (Button) findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("tag", String.valueOf(MyObservable.getInstance().countObservers()));
//看一下這個被觀察者 有幾個觀察者在觀察
Intent intent = new Intent(MainActivity2Activity.this , MainActivity.class);
startActivity(intent);
//換到第一頁
finish();
//關閉這頁
}
});
}
view raw gistfile1.java hosted with ❤ by GitHub


理論上應該都是一個觀察者在觀察,因為上一頁被finish了,但是因為沒deleteObserver,

所以你會看到那個數字一直在上升。

這感覺不太妙對吧,明明那個觀察者已經不見了,但是他還是被算在觀察者之中,你的

Activity會因為這樣而被保留下來,但是因為finish了,你無法去存取他,簡單的說會有一個

無法存取的物件,存在記憶體之中,累計很多的話可能會有不可預期的錯誤。

因此還是要養成deleteObserver的好習慣。

沒有留言:

張貼留言