編輯:關於Android編程
同樣,一個軟件系統常常要求在某一個對象的狀態發生變化的時候,某些其他的對象做出相應的改變。做到這一點的設計方案有很多,但是為了使系統能夠易於復用,應該選擇低耦合度的設計方案。減少對象之間的耦合有利於系統的復用,但是同時設計師需要使這些低耦合度的對象之間能夠維持行動的協調一致,保證高度的協作。觀察者模式是滿足這一要求的各種設計方案中最重要的一種。(上文源於網絡)
上圖是觀察者模式的基本模型,以通話狀態(CallState)為例,來分析手機通話狀態變化時,是怎麼傳遞這個事件的。
RegistrantList作為通知者,Registrant為觀察者,RegistrantList通知者提供了add、remove、notifyRegistrants來管理Registrant。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PHN0cm9uZz4xoaLNqLuw17TMrMrH1PXDtLG7vODM/bXEPzwvc3Ryb25nPjxicj4KPC9wPgo8cD5tQ2FsbFN0YXRlUmVnaXN0cmFudHPKx1JlZ2lzdHJhbnRMaXN0tcTSu7j2ttTP86Os1NpCYXNlQ29tbWFuZC5qYXZh1tDJ+rPJo6yyorbUUmVnaXN0cmFudExpc3TNqNaq1d+1xMztvNOhosm+s/3X9sHLt+LXsKO6PC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;">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); }
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);
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: if (RILJ_LOGD) unsljLog(response); mCallStateRegistrants .notifyRegistrants(new AsyncResult(null, null, null)); break;
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); } }
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 手機上使用 Terminal IDE 遠程登錄你的 Mac 可以讓你隨時隨地遠程對你
什麼是反射?反射是一種能夠在程序運行時動態訪問、修改某個類中任意屬性(狀態)和方法(行為)的機制(包括private實例和方法),java反射機制提供了以下幾個功能:在運
簡介: 在自定義view的時候,其實很簡單,只需要知道3步驟: 1.測量——onMeasure():決定View的大小 2.布局—&m
先來一張效果圖 一.ActionBar的設計首先是main.xml,先定義這些菜單,界面稍後在調整<menu xmlns:android=http://schema