Android Telephony分析(二) ---- RegistrantList详解
前言
本文主要講解RegistrantList的原理,以及如何快速分析RegistrantList相關(guān)的代碼流程。?
在Telephony模塊中,在RIL、Tracker(ServiceStateTracker、CallTracker、DcTracker)、Phone(PhoneBase及其子類(lèi))、UICC框架、CallManager等等中都大量使用到的RegistrantList,可見(jiàn)RegistrantList使用范圍之廣。如果代碼流程中使用了RegistrantList,如何分析下一步代碼流程走到哪里也是必須掌握的技能。
1. RegistrantList的原理
在講解RegistrantList之前,先引出觀察者模式的概念:
觀察者模式:定義對(duì)象間的一種一(Subject)對(duì)多(Observer)的依賴(lài)關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都得到通知并且自動(dòng)更新。
RegistrantList跟觀察者模式有點(diǎn)類(lèi)似,先創(chuàng)建一個(gè)RegistrantList集合,專(zhuān)門(mén)關(guān)注某種消息;如果有人也對(duì)該消息感興趣的話,那么為他封裝一個(gè)Registrant對(duì)象并且添加到RegistrantList中;當(dāng)有消息上報(bào)時(shí),先通知RegistrantList,接著所有注冊(cè)到RegistrantList中的Registrant都會(huì)被通知到并且更新。
RegistrantList與Registrant的關(guān)系如下:?
RegistrantList中有:?
add()/addUnique()方法,用于增加一個(gè)Registrant;?
remove()方法,用于刪除一個(gè)Registrant;?
internalNotifyRegistrants()方法,用于通知所有的Registrant。
而Registrant中有:?
internalNotifyRegistrants()方法,用于在收到RegistrantList的通知之后,再更新自己的內(nèi)容。
本文來(lái)自http://blog.csdn.net/linyongan?,轉(zhuǎn)載請(qǐng)務(wù)必注明出處。
2. RegistrantList的使用
我們?cè)谏弦黄恼隆禔ndroid Telephony分析(一) —- Phone詳解 》中曾經(jīng)說(shuō)到Phone接口中有大量的register/unregister的方法,為了跟上一篇文章相呼應(yīng),那么我們就選PhoneBase.java中監(jiān)聽(tīng)通話掛斷的mDisconnectRegistrants作為例子分析一下吧。?
(時(shí)序圖中的編號(hào)對(duì)應(yīng)下面代碼注釋中的編號(hào))
2.1 創(chuàng)建RegistrantList
在PhoneBase初始化的時(shí)候,會(huì)創(chuàng)建mDisconnectRegistrants用于監(jiān)聽(tīng)通話掛斷這個(gè)事件。
//1.創(chuàng)建RegistrantList-->監(jiān)聽(tīng)通話掛斷protected final RegistrantList mDisconnectRegistrants= new RegistrantList();//對(duì)應(yīng)地也會(huì)封裝好增加Registrant/刪除Registrant的方法,//然后提供register/unregister方法給外界調(diào)用,@Overridepublic void registerForDisconnect(Handler h, int what, Object obj) {checkCorrectThread(h);//3.增加一個(gè)RegistrantmDisconnectRegistrants.addUnique(h, what, obj);}@Overridepublic void unregisterForDisconnect(Handler h) {//根據(jù)Handler刪除RegistrantmDisconnectRegistrants.remove(h);}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
在RegistrantList的內(nèi)部:
public class RegistrantList {//用一個(gè)列表來(lái)存儲(chǔ)所有的Registrant。//有點(diǎn)好奇源碼中為什么不用泛型?:ArrayList<Registrant> registrants = new ArrayList<Registrant>(); ArrayList registrants = new ArrayList();// of Registrantpublic synchronized voidadd(Handler h, int what, Object obj){ //創(chuàng)建一個(gè)Registrantadd(new Registrant(h, what, obj));}public synchronized voidaddUnique(Handler h, int what, Object obj){// if the handler is already in the registrant list, remove itremove(h);//4.創(chuàng)建一個(gè)Registrantadd(new Registrant(h, what, obj)); }public synchronized voidadd(Registrant r){removeCleared();//5.把Registrant添加到registrants列表中registrants.add(r);}public synchronized voidremove(Handler h){//遍歷列表中的Registrantfor (int i = 0, s = registrants.size() ; i < s ; i++) {Registrant r = (Registrant) registrants.get(i);Handler rh;rh = r.getHandler();/* Clean up both the requested registrant and* any now-collected registrants*/if (rh == null || rh == h) {//清空Registrant的內(nèi)容r.clear();}}removeCleared();}public synchronized voidremoveCleared(){for (int i = registrants.size() - 1; i >= 0 ; i--) {Registrant r = (Registrant) registrants.get(i);if (r.refH == null) {//移除Handler為空的Registrantregistrants.remove(i);}}}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
2.2 注冊(cè)監(jiān)聽(tīng)某個(gè)消息
在TelephonyConnection.java中
//2.注冊(cè)監(jiān)聽(tīng)某個(gè)消息getPhone().registerForDisconnect(mHandler, MSG_DISCONNECT, null);private final Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_DISCONNECT://10.最終代碼流程會(huì)走到這里,對(duì)之前監(jiān)聽(tīng)的消息作進(jìn)一步處理break;}}}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2.3 發(fā)送通知
當(dāng)收到通話掛斷的消息后,先通知RegistrantList
/*package*/ voidnotifyDisconnect(Connection cn) {//6.開(kāi)始通知所有注冊(cè)到mDisconnectRegistrants中的RegistrantmDisconnectRegistrants.notifyResult(cn);}- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
在RegistrantList的內(nèi)部:
public /*synchronized*/ voidnotifyResult(Object result){internalNotifyRegistrants (result, null);}private synchronized voidinternalNotifyRegistrants (Object result, Throwable exception){ //7.遍歷registrants列表for (int i = 0, s = registrants.size(); i < s ; i++) {Registrant r = (Registrant) registrants.get(i);//8.通知Registrantr.internalNotifyRegistrant(result, exception);}}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
來(lái)到Registrant里:
internalNotifyRegistrant (Object result, Throwable exception){ //得到Handler對(duì)象Handler h = getHandler();if (h == null) {clear();} else {Message msg = Message.obtain();msg.what = what;msg.obj = new AsyncResult(userObj, result, exception);//9.通過(guò)回調(diào),給Handler發(fā)送Messageh.sendMessage(msg);}}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
整個(gè)RegistrantList注冊(cè)Registrant,再到通知Registrant這個(gè)過(guò)程,也是利用了回調(diào),可以留意時(shí)序圖中,步驟2~步驟10,折騰了半天,最后還是回到TelephonyConnection中去。?
回顧上面第二小節(jié)的代碼:?
TelephonyConnection對(duì)PhoneBase說(shuō),你幫我留意一下通話掛斷這個(gè)消息啊!?
PhoneBase說(shuō),什么時(shí)候有通話掛斷消息來(lái)我也不清楚啊,要不你留個(gè)聯(lián)系方式給我??
TelephonyConnection就傳遞了Handler和消息類(lèi)型給PhoneBase,然后自己就去忙其他事了。?
PhoneBase通過(guò)RegistrantList,把TelephonyConnection的聯(lián)系方式(Handler和消息類(lèi)型)傳遞給了Registrant。?
等到通話掛斷消息上報(bào)時(shí),RegistrantList先通知Registrant,然后Registrant就給TelephonyConnection發(fā)消息。
3. 學(xué)以致用
代碼中使用了RegistrantList,如何快速分析下一步流程走到哪里??
這是一個(gè)回調(diào)的過(guò)程,所以核心就是在哪里注冊(cè)就在哪里處理,我們要找到調(diào)用register方法的地方。?
還是以第二小節(jié)的mDisconnectRegistrants為例,假如我們不知道第二小節(jié)的內(nèi)容,我們分析到這里:
- 1
- 1
先搜索mDisconnectRegistrants,找到registerXXX的方法;
public void registerForDisconnect(Handler h, int what, Object obj) {checkCorrectThread(h);mDisconnectRegistrants.addUnique(h, what, obj);}- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
再搜索registerXXX方法,找到調(diào)用register方法的地方;
getPhone().registerForDisconnect(mHandler, MSG_DISCONNECT, null);- 1
- 1
最后搜索”MSG_DISCONNECT”,找到handleMessage()方法對(duì)MSG_DISCONNECT消息的處理,所以下一步代碼流程就應(yīng)該是走這里了。
原文地址:http://blog.csdn.net/linyongan/article/details/52036225
總結(jié)
以上是生活随笔為你收集整理的Android Telephony分析(二) ---- RegistrantList详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android Service 形式分类
- 下一篇: Android Telephony分析(