[Android-Java]使用觀察者的正確姿勢(shì)

前言

首先先問(wèn)一個(gè)問(wèn)題误债,你在做Android開(kāi)發(fā)的時(shí)候有沒(méi)有被傳值整的蒙圈蔬顾?例如Fragment之間的傳值隅居,Activity之間的傳值(ActivityForResult比較常用)峡碉,F(xiàn)ragment與Activity之間的傳值等等等等须揣。
先列舉幾個(gè)簡(jiǎn)單的回傳例子吧盐股。

1.Activity之間的傳值:Intent,startActivityForResult等等耻卡。
2.廣播傳值:BroadcastReceiver疯汁。
3.接口回調(diào)機(jī)制,也叫作代理模式卵酪,Android中經(jīng)常用到幌蚊。
4.線程間傳值:Handler模式
5.Service與Activity之間的傳值:ServiceConnection

如果你是Android的新手,那這幾種東西都是很有必要了解的溃卡,其中比較難理解的應(yīng)該就是接口回調(diào)機(jī)制了溢豆。反正我講課的時(shí)候,基本上所有的學(xué)生在初次接觸之后瘸羡,肯定蒙圈~

一漩仙、機(jī)制

那么言歸正傳,我們接下來(lái)呢犹赖,要講解的就是一種新的傳值方式队他,也是一種比較簡(jiǎn)單的方式----觀察者
首先我們來(lái)看一下觀察者的機(jī)制一幅圖,很簡(jiǎn)單就可以理解峻村。

觀察者機(jī)制.png

我們來(lái)簡(jiǎn)單的講解一下上面的圖片:
A:被觀察者麸折,信息的起點(diǎn),用來(lái)包裝信息
O:觀察者粘昨,信息的中轉(zhuǎn)站垢啼,用來(lái)傳遞信息
B:被改變者窜锯,信息的終點(diǎn),用來(lái)處理信息

第一步:先把被改變者B芭析,放入觀察者O專門準(zhǔn)備的一個(gè)表中衬浑,注冊(cè)一下。
第二步:當(dāng)被觀察者A放刨,觸發(fā)觀察者事件時(shí)工秩,發(fā)送通知給觀察者O。
第三步:觀察者O进统,會(huì)掃描自己的注冊(cè)表助币,如果發(fā)現(xiàn)有注冊(cè)者,也就是被改變者B存在的話螟碎,則進(jìn)行第四步眉菱。
第四步:觀察者O,把從被觀察者A處得到的信息掉分,發(fā)送給被改變者B俭缓。

二、使用

說(shuō)了這么多酥郭,咱們來(lái)簡(jiǎn)單的看一個(gè)例子:從Activity傳值到Fragment华坦。我覺(jué)得這是很多人都一直頭疼的一個(gè)問(wèn)題。

9834458E-C584-41D8-A8D6-59278836E0DF.png

從上圖可以看出不从,Activity中有一個(gè)輸入框和按鈕惜姐。Fragment中就很簡(jiǎn)單了,就只有一個(gè)TextView椿息,我們現(xiàn)在想做的就是要在Activity的EditText輸入框中輸入內(nèi)容歹袁,當(dāng)點(diǎn)擊提交的時(shí)候,在Fragment的TextView中顯示Activity的EditText中輸入的內(nèi)容寝优。
在看代碼之前呢条舔,我們先來(lái)理清一下思路。確定一下誰(shuí)是被觀察者A乏矾,誰(shuí)是被改變者B孟抗,當(dāng)然,觀察者O是一個(gè)單獨(dú)的類妻熊,他們兩個(gè)肯定都不是夸浅。

被改變者:Fragment

被觀察者:Activity

好的,我們已經(jīng)確定了被觀察者和被改變者扔役。下面我們先來(lái)把我們的觀察者類寫一下帆喇。

public class MyObserverable extends Observable {

    public static MyObserverable observerable;

    // 單例:在所有內(nèi)存中,只存在一個(gè)此對(duì)象
    public static MyObserverable getObserverable() {
        if (observerable == null) {
            observerable = new MyObserverable();
        }
        return observerable;
    }

    public void setMessage(Object msg) {
        // 告訴觀察者對(duì)象亿胸,所觀察的內(nèi)容發(fā)生改變
        observerable.setChanged();
        // 刷新信息坯钦,或者信息傳遞
        observerable.notifyObservers(msg);
    }

}

這里我用的是一個(gè)單例预皇,簡(jiǎn)單明確,并且很好用的哦~最基本的東西觀察者已經(jīng)做好了婉刀,在這里我們可以看到吟温,觀察者在Java中是一個(gè)單獨(dú)的類,Observable突颊。

下面就要使用這個(gè)觀察者類了鲁豪,就遵循我們之前所說(shuō)的觀察者機(jī)制就好。

第一步:先把被改變者B律秃,放入觀察者O專門準(zhǔn)備的一個(gè)表中爬橡,注冊(cè)一下。
public class Fragment01 extends Fragment implements Observer {
    TextView tv;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View v = inflater.inflate(R.layout.f1, null);
        tv = (TextView) v.findViewById(R.id.textView1);
        // 注冊(cè)觀察者
        MyObserverable.getObserverable().addObserver(this);
        return v;
    }

    // 當(dāng)我們告訴觀察者棒动,信息發(fā)生改變的時(shí)候糙申,調(diào)用此方法
    @Override
    public void update(Observable observable, Object data) {
        tv.setText(data.toString());
    }
}

因?yàn)槲疫@里面是使用的單例類,所以我直接通過(guò)調(diào)用MyOserverable的靜態(tài)方法獲取的觀察者對(duì)象船惨。

第二步:當(dāng)被觀察者A柜裸,觸發(fā)觀察者事件時(shí),發(fā)送通知給觀察者O粱锐。

public class MainActivity extends FragmentActivity {
    EditText et;
    Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et = (EditText) findViewById(R.id.et);
        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                String str = et.getText().toString();
                // 當(dāng)事件觸發(fā)疙挺,通知觀察者
                MyObserverable.getObserverable().setMessage(str);

            }
        });
    }

}
第三步:觀察者O,會(huì)掃描自己的注冊(cè)表卜范,如果發(fā)現(xiàn)有注冊(cè)者衔统,也就是被改變者B存在的話鹿榜,則進(jìn)行第四步海雪。
public class MyObserverable extends Observable {

    ...
        // 掃描注冊(cè)表
    public void setMessage(Object msg) {
        // 告訴觀察者對(duì)象,所觀察的內(nèi)容發(fā)生改變
        observerable.setChanged();
        // 刷新信息舱殿,或者信息傳遞
        observerable.notifyObservers(msg);
    }

}

我們?cè)趯懹^察者類的時(shí)候奥裸,已經(jīng)完成了這一步。

第四步:觀察者O沪袭,把從被觀察者A處得到的信息湾宙,發(fā)送給被改變者B。
public class Fragment01 extends Fragment implements Observer {
    ...

    // 當(dāng)我們告訴觀察者冈绊,信息發(fā)生改變的時(shí)候侠鳄,調(diào)用此方法
    @Override
    public void update(Observable observable, Object data) {
        tv.setText(data.toString());
    }
}

在第一步的代碼中其實(shí)我們已經(jīng)實(shí)現(xiàn)了處理方法:即實(shí)現(xiàn)Observer接口,并實(shí)現(xiàn)接口中的抽象方法update()死宣。

這就是觀察者的使用步驟伟恶,是不是很簡(jiǎn)單?來(lái)試試吧毅该。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末博秫,一起剝皮案震驚了整個(gè)濱河市潦牛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挡育,老刑警劉巖巴碗,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異即寒,居然都是意外死亡橡淆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門母赵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)明垢,“玉大人,你說(shuō)我怎么就攤上這事市咽∪” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵施绎,是天一觀的道長(zhǎng)溯革。 經(jīng)常有香客問(wèn)我,道長(zhǎng)谷醉,這世上最難降的妖魔是什么致稀? 我笑而不...
    開(kāi)封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮俱尼,結(jié)果婚禮上抖单,老公的妹妹穿的比我還像新娘。我一直安慰自己遇八,他們只是感情好矛绘,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著刃永,像睡著了一般货矮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斯够,一...
    開(kāi)封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天囚玫,我揣著相機(jī)與錄音,去河邊找鬼读规。 笑死抓督,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的束亏。 我是一名探鬼主播铃在,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼枪汪!你這毒婦竟也來(lái)了涌穆?” 一聲冷哼從身側(cè)響起怔昨,我...
    開(kāi)封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宿稀,沒(méi)想到半個(gè)月后趁舀,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祝沸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年矮烹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罩锐。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奉狈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涩惑,到底是詐尸還是另有隱情仁期,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布竭恬,位于F島的核電站跛蛋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏痊硕。R本人自食惡果不足惜赊级,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望岔绸。 院中可真熱鬧理逊,春花似錦、人聲如沸盒揉。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)预烙。三九已至墨微,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扁掸,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工最域, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谴分,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓镀脂,卻偏偏與公主長(zhǎng)得像牺蹄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子薄翅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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

  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 8,977評(píng)論 0 13
  • 面試題總結(jié) 通用 安卓學(xué)習(xí)途徑, 尋找資料學(xué)習(xí)的博客網(wǎng)站 AndroidStudio使用, 插件使用 安卓和蘋果的...
    JingBeibei閱讀 1,650評(píng)論 2 21
  • Java基礎(chǔ) 什么是重載沙兰,什么是重寫氓奈?有什么區(qū)別?重載(Overload):(1)Overloading是一個(gè)類中...
    勤息嘻嘻嘻閱讀 637評(píng)論 0 1
  • 最近剛從舊公司離職鼎天,為面試在做準(zhǔn)備舀奶,因?yàn)槠綍r(shí)開(kāi)發(fā)CV大法用得比較多,很多基礎(chǔ)知識(shí)掌握得不是很牢靠以及很多工具框架只...
    黎清海閱讀 2,171評(píng)論 1 19
  • 一斋射、查看內(nèi)存育勺、cpu情況 參考鏈接[https://blog.csdn.net/mydriverc2/articl...
    WAHAHA402閱讀 1,425評(píng)論 0 1