Android觀察者模式的理解

觀察者模式的定義

觀察者定義了一個一對多的依賴關(guān)系,讓一個或者多個觀察者監(jiān)聽一個主題(被觀察者)的變化陨闹。因此薄坏,當(dāng)主題狀態(tài)發(fā)生變化時寨闹,主題會通知觀察者,使觀察者能夠自動更新沈善。

被觀察者的特點

  • 持有監(jiān)聽的觀察者的引用
  • 支持增加和刪除觀察者
  • 主題狀態(tài)改變,通知觀察者

觀察者的特點

接收到被觀察者狀態(tài)發(fā)生變化時做出變化闻牡。

如何實現(xiàn)

  • 觀察者實現(xiàn)Observer接口即可
  • 被觀察者繼承Observable即可

示例代碼

    package com.example.mazhihao.observerdemo;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;



    public class MainActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Organization organization = new Organization();
                    organization.setMsg("Hello Observer...");
                    Member member = new Member(MainActivity.this);
                    organization.addObserver(member);//添加一個觀察者
                    organization.display();
                    Log.i("mzh", "observer count is " + organization.countObservers());
                    organization.deleteObserver(member);
                    Log.i("mzh", "observer count is " + organization.countObservers());
                }
            });

        }
    }

觀察者

    package com.example.mazhihao.observerdemo;

    import android.content.Context;
    import android.widget.Toast;

    import java.util.Observable;
    import java.util.Observer;

    /**
     * Created by mazhihao on 2016/7/13.
     */
    public class Member implements Observer {
        private Context context;

        public Member(Context context) {
            this.context = context;
        }

        @Override
        public void update(Observable observable, Object data) {
            String msg = ((Organization) observable).getMsg();
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        }
    }

被觀察者

    package com.example.mazhihao.observerdemo;

    import java.util.Observable;

    /**
     * Created by mazhihao on 2016/7/13.
     */
    public class Organization extends Observable {
        private String msg;

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public void display() {
            this.setChanged();//改變狀態(tài)
            this.notifyObservers();
        }
    }
關(guān)注要點

主題發(fā)生改變時玖翅,需要調(diào)用setChange()方法金度,表示狀態(tài)放生改變严沥。下面看看這個方法的具體實現(xiàn)

    /**
     * Sets the changed flag for this {@code Observable}. After calling
     * {@code setChanged()}, {@code hasChanged()} will return {@code true}.
     */
    protected void setChanged() {
        changed = true;
    }

再來看看notifyObservers()這個方法的具體實現(xiàn):

    /**
     * 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);
            }
        }
    }

總結(jié)

當(dāng)主題狀態(tài)發(fā)生變化時消玄,必須要調(diào)用setChange()方法改變標(biāo)記,然后調(diào)用notifyObservers()方法通知所有的觀察者才會生效翩瓜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奥溺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子相满,更是在濱河造成了極大的恐慌桦卒,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件建蹄,死亡現(xiàn)場離奇詭異裕偿,居然都是意外死亡,警方通過查閱死者的電腦和手機劲腿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門鸟妙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挥吵,“玉大人花椭,你說我怎么就攤上這事矿辽〉ぴ剩” “怎么了嗦锐?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵奕污,是天一觀的道長。 經(jīng)常有香客問我碳默,道長,這世上最難降的妖魔是什么嘱根? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任该抒,我火速辦了婚禮,結(jié)果婚禮上凑保,老公的妹妹穿的比我還像新娘。我一直安慰自己频伤,他們只是感情好芝此,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布婚苹。 她就那樣靜靜地躺著,像睡著了一般租副。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上结胀,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天责循,我揣著相機與錄音,去河邊找鬼秸抚。 笑死歹垫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的排惨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鹿驼,長吁一口氣:“原來是場噩夢啊……” “哼辕宏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瑞筐,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤聚假,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魔策,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匈子,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡虎敦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年其徙,在試婚紗的時候發(fā)現(xiàn)自己被綠了喷户。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡闹获,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出避诽,到底是詐尸還是另有隱情,我是刑警寧澤鲤妥,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布拱雏,位于F島的核電站,受9級特大地震影響贡耽,放射性物質(zhì)發(fā)生泄漏羡滑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一凳宙、第九天 我趴在偏房一處隱蔽的房頂上張望职祷。 院中可真熱鬧,春花似錦是尖、人聲如沸泥耀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逸吵,卻和暖如春缝裁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工氢妈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扰才,地道東北人厕怜。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓粥航,卻偏偏與公主長得像,于是被迫代替她去往敵國和親柄延。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容