Android與設計模式——觀察者(Observer)模式

來源:互聯網
上載者:User

Android與設計模式——觀察者(Observer)模式
在閻宏博士的《JAVA與模式》一書中開頭是這樣描述觀察者(Observer)模式的:

  觀察者模式是對象的行為模式,又叫發布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
  觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。


觀察者模式的結構
  一個軟體系統裡麵包含了各種對象,就像一片欣欣向榮的森林充滿了各種生物一樣。在一片森林中,各種生物彼此依賴和約束,形成一個個生物鏈。一種生物的狀態變化會造成其他一些生物的相應行動,每一個生物都處於別的生物的互動之中。

  同樣,一個軟體系統常常要求在某一個對象的狀態發生變化的時候,某些其他的對象做出相應的改變。做到這一點的設計方案有很多,但是為了使系統能夠易於複用,應該選擇低耦合度的設計方案。減少對象之間的耦合有利於系統的複用,但是同時設計師需要使這些低耦合度的對象之間能夠維持行動的協調一致,保證高度的協作。觀察者模式是滿足這一要求的各種設計方案中最重要的一種。(上文源於網路)



是觀察者模式的基本模型,以通話狀態(CallState)為例,來分析手機通話狀態變化時,是怎麼傳遞這個事件的。

RegistrantList作為通知者,Registrant為觀察者,RegistrantList通知者提供了add、remove、notifyRegistrants來管理Registrant。

1、通話狀態是怎麼被監聽的?

mCallStateRegistrants是RegistrantList的一個對象,在BaseCommand.java中產生,並對RegistrantList通知者的添加、刪除做了封裝:

protected RegistrantList mCallStateRegistrants = new RegistrantList();

    public void registerForCallStateChanged(Handler h, int what, Object obj) {        Registrant r = new Registrant (h, what, obj);//觀察者        mCallStateRegistrants.add(r);    }    public void unregisterForCallStateChanged(Handler h) {        mCallStateRegistrants.remove(h);    }

registerForCallStateChanged中new了一個Registrant觀察者,將其加入到通知者中,來看Registrant是怎麼儲存的?

    public synchronized void    add(Registrant r)    {        removeCleared();        registrants.add(r);    }
registrants是一個 ArrayList對象,管理Registrant其實就是對 ArrayList的操作。

registerForCallStateChanged是在GsmCallTracker.java的建構函式被調用的:

mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
this就是GsmCallTracker本身,GsmCallTracker繼承了Handler,此處,也就是說GsmCallTracker成為了觀察者,當CallState變化時mCallStateRegistrants應該通知GsmCallTracker。
當不需要監聽時,可登出:

mCi.unregisterForCallStateChanged(this);


2、mCallStateRegistrants是怎麼通知GsmCallTracker CallState變化了?
在手機中,當通話狀態發生改變,Modem會向上傳遞訊息,傳到framework時,被RIL.java接收處理:

            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:                if (RILJ_LOGD) unsljLog(response);                mCallStateRegistrants                    .notifyRegistrants(new AsyncResult(null, null, null));            break;

mCallStateRegistrants使用notifyRegistrants來通知它的所有觀察者:

    public /*synchronized*/ void    notifyResult(Object result)    {        internalNotifyRegistrants (result, null);    }    private synchronized void    internalNotifyRegistrants (Object result, Throwable exception)    {       for (int i = 0, s = registrants.size(); i < s ; i++) {            Registrant  r = (Registrant) registrants.get(i);            r.internalNotifyRegistrant(result, exception);       }    }

registrants就是之前儲存所有觀察者的ArrayList,遍曆,通知。

3、觀察者Registrant是怎麼響應處理通知的?

上面看到r.internalNotifyRegistrant(result, exception),觀察者知道callstate發生變化後,誰來真正處理?

Registrant部分代碼:

    internalNotifyRegistrant (Object result, Throwable exception)    {        Handler h = getHandler();        if (h == null) {            clear();            /// M: Registrant Debug Log Enhancement            Log.d("Registrant", "internalNotifyRegistrant(): Warning! Handler is null, it could be already GCed. ( what=" + what + ", userObj=" + userObj + ", result=" + result + ", exception=" + exception + " )");        } else {            Message msg = Message.obtain();            msg.what = what;                        msg.obj = new AsyncResult(userObj, result, exception);                        h.sendMessage(msg);        }    }
Handler h = getHandler();獲得的Handler就是上文說到的this,也就是GsmCallTracker,what就是registerForCallStateChanged註冊時的第二個參數EVENT_CALL_STATE_CHANGE,這裡h.sendMessage也就是用的GsmCallTracker這個Handler發送的訊息。我們都知道,Handler發送的訊息都會被它自己的handleMessage()方法所接收處理。

於是,我們在GsmCallTracker的handleMessage()方法中看到:

            case EVENT_CALL_STATE_CHANGE:                pollCallsWhenSafe();            break;
具體做什麼操作,我們就不管了。。。

Android Telephony源碼中用到了大量的觀察者模式,理解觀察者模式,有助於我們閱讀源碼。

未完待續,有不對的地方,請指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.