日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Telephony分析(二) ---- RegistrantList详解

發布時間:2025/3/15 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Telephony分析(二) ---- RegistrantList详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本文主要講解RegistrantList的原理,以及如何快速分析RegistrantList相關的代碼流程。?
在Telephony模塊中,在RIL、Tracker(ServiceStateTracker、CallTracker、DcTracker)、Phone(PhoneBase及其子類)、UICC框架、CallManager等等中都大量使用到的RegistrantList,可見RegistrantList使用范圍之廣。如果代碼流程中使用了RegistrantList,如何分析下一步代碼流程走到哪里也是必須掌握的技能。

1. RegistrantList的原理

在講解RegistrantList之前,先引出觀察者模式的概念:

觀察者模式:定義對象間的一種一(Subject)對多(Observer)的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并且自動更新。

RegistrantList跟觀察者模式有點類似,先創建一個RegistrantList集合,專門關注某種消息;如果有人也對該消息感興趣的話,那么為他封裝一個Registrant對象并且添加到RegistrantList中;當有消息上報時,先通知RegistrantList,接著所有注冊到RegistrantList中的Registrant都會被通知到并且更新。

RegistrantList與Registrant的關系如下:?

RegistrantList中有:?
add()/addUnique()方法,用于增加一個Registrant;?
remove()方法,用于刪除一個Registrant;?
internalNotifyRegistrants()方法,用于通知所有的Registrant。

而Registrant中有:?
internalNotifyRegistrants()方法,用于在收到RegistrantList的通知之后,再更新自己的內容。


http://blog.csdn.net/linyongan?。


2. RegistrantList的使用

我們在上一篇文章《Android Telephony分析(一) —- Phone詳解 》中曾經說到Phone接口中有大量的register/unregister的方法,為了跟上一篇文章相呼應,那么我們就選PhoneBase.java中監聽通話掛斷的mDisconnectRegistrants作為例子分析一下吧。?

(時序圖中的編號對應下面代碼注釋中的編號)

2.1 創建RegistrantList

在PhoneBase初始化的時候,會創建mDisconnectRegistrants用于監聽通話掛斷這個事件。

//1.創建RegistrantList-->監聽通話掛斷protected final RegistrantList mDisconnectRegistrants= new RegistrantList();//對應地也會封裝好增加Registrant/刪除Registrant的方法,//然后提供register/unregister方法給外界調用,@Overridepublic void registerForDisconnect(Handler h, int what, Object obj) {checkCorrectThread(h);//3.增加一個RegistrantmDisconnectRegistrants.addUnique(h, what, obj);}@Overridepublic void unregisterForDisconnect(Handler h) {//根據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的內部:

public class RegistrantList {//用一個列表來存儲所有的Registrant。//有點好奇源碼中為什么不用泛型?:ArrayList<Registrant> registrants = new ArrayList<Registrant>(); ArrayList registrants = new ArrayList();// of Registrantpublic synchronized voidadd(Handler h, int what, Object obj){ //創建一個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.創建一個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的內容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 注冊監聽某個消息

在TelephonyConnection.java中

//2.注冊監聽某個消息getPhone().registerForDisconnect(mHandler, MSG_DISCONNECT, null);private final Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_DISCONNECT://10.最終代碼流程會走到這里,對之前監聽的消息作進一步處理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 發送通知

當收到通話掛斷的消息后,先通知RegistrantList

/*package*/ voidnotifyDisconnect(Connection cn) {//6.開始通知所有注冊到mDisconnectRegistrants中的RegistrantmDisconnectRegistrants.notifyResult(cn);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在RegistrantList的內部:

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

來到Registrant里:

internalNotifyRegistrant (Object result, Throwable exception){ //得到Handler對象Handler h = getHandler();if (h == null) {clear();} else {Message msg = Message.obtain();msg.what = what;msg.obj = new AsyncResult(userObj, result, exception);//9.通過回調,給Handler發送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

整個RegistrantList注冊Registrant,再到通知Registrant這個過程,也是利用了回調,可以留意時序圖中,步驟2~步驟10,折騰了半天,最后還是回到TelephonyConnection中去。?
回顧上面第二小節的代碼:?
TelephonyConnection對PhoneBase說,你幫我留意一下通話掛斷這個消息啊!?
PhoneBase說,什么時候有通話掛斷消息來我也不清楚啊,要不你留個聯系方式給我??
TelephonyConnection就傳遞了Handler和消息類型給PhoneBase,然后自己就去忙其他事了。?
PhoneBase通過RegistrantList,把TelephonyConnection的聯系方式(Handler和消息類型)傳遞給了Registrant。?
等到通話掛斷消息上報時,RegistrantList先通知Registrant,然后Registrant就給TelephonyConnection發消息。

3. 學以致用

代碼中使用了RegistrantList,如何快速分析下一步流程走到哪里??
這是一個回調的過程,所以核心就是在哪里注冊就在哪里處理,我們要找到調用register方法的地方。?
還是以第二小節的mDisconnectRegistrants為例,假如我們不知道第二小節的內容,我們分析到這里:

mDisconnectRegistrants.notifyResult(cn);
  • 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方法,找到調用register方法的地方;

getPhone().registerForDisconnect(mHandler, MSG_DISCONNECT, null);
  • 1
  • 1

最后搜索”MSG_DISCONNECT”,找到handleMessage()方法對MSG_DISCONNECT消息的處理,所以下一步代碼流程就應該是走這里了。

原文地址:http://blog.csdn.net/linyongan/article/details/52036225

總結

以上是生活随笔為你收集整理的Android Telephony分析(二) ---- RegistrantList详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。