老李推荐: 第8章4节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 1...
老李推薦: 第8章4節(jié)《MonkeyRunner源碼剖析》MonkeyRunner啟動(dòng)運(yùn)行過程-啟動(dòng)AndroidDebugBridge
上一節(jié)我們看到在啟動(dòng)AndroidDebugBridge的過程中會(huì)調(diào)用其start方法,而該方法會(huì)做2個(gè)主要的事情:
其中第一點(diǎn)我們上一小節(jié)已經(jīng)做了詳盡分析了,那么我們往下就去分析下第2點(diǎn)。
DeviceMonitor主要的功能就是監(jiān)控是否有安卓設(shè)備拔除或者連接上來,然后對每個(gè)連接上來的設(shè)備的所有可調(diào)式進(jìn)程進(jìn)行監(jiān)控。這個(gè)功能更多是給DDMS這個(gè)調(diào)試工具使用的,大家從AndroidDebugBridge所在的jar包ddmlib.jar應(yīng)該就能猜到其實(shí)DDMS用到的也是這個(gè)jar包。
Android的每一個(gè)應(yīng)用程序都是運(yùn)行在獨(dú)立的進(jìn)程中的,且每個(gè)進(jìn)程都是在自己的虛擬機(jī)(VM)中運(yùn)行的,其實(shí)這個(gè)就基本上是Android操作系統(tǒng)的沙箱(SandBox)的概念了。目的就是以防你的進(jìn)程到處亂闖搞破壞。每個(gè)進(jìn)程的VM都會(huì)提供唯一的一個(gè)端口作連接調(diào)試器用。DDMS啟動(dòng)時(shí)會(huì)連接到AndroidDebugBridge(也就是ADB服務(wù)器了)。當(dāng)一個(gè)設(shè)備被連接時(shí),一個(gè)虛擬機(jī)在設(shè)備上啟動(dòng)或停止時(shí)它會(huì)通知DDMS,在DDMS和adb之間創(chuàng)建一個(gè)虛擬機(jī)的監(jiān)控服務(wù)。一旦虛擬機(jī)運(yùn)行,DDMS會(huì)通過AndroidDebugBridge的DeviceMonitor線程檢索虛擬機(jī)的進(jìn)程ID(pid),并通過設(shè)備上的adb守護(hù)進(jìn)程打開一個(gè)連接到虛擬機(jī)的調(diào)試器。這樣DDMS就能和虛擬機(jī)對話了。
?
圖8-4-1 DDMS界面
DeviceMonitor這個(gè)類對于MonkeyRunner框架來說最重要的功能是它保存了一個(gè)代表所有連接上來的設(shè)備的Device列表,這個(gè)Device類非常的重要,基本可以說MonkeyRunner和ADB服務(wù)器的溝通最終都是通過它來做的,所以它相當(dāng)于一個(gè)安卓設(shè)備在PC端的代理,我們下一章會(huì)對這個(gè)類做詳細(xì)的分析。下面我們先看下DeviceMonitor這個(gè)類:
?
圖8-4-2 DeviceMonitor類
這個(gè)類是ddmlib庫的一個(gè)類,上面類圖列出了DeviceMonitor關(guān)鍵的成員變量和方法,我們先對它們做初步的介紹,這樣有利于大家更好的跟隨我在下面對這個(gè)類的源代碼進(jìn)行分析:
- mServer: DebugBridgeServer對象,因?yàn)樾枰駻DB服務(wù)器發(fā)送相應(yīng)的設(shè)備監(jiān)控命令,所以在DeviceMonitor初始化的時(shí)候會(huì)把一個(gè)DebugBridgeServer實(shí)例傳進(jìn)來保存到mServer中
- mMainAdbConnection: 一個(gè)SocketChannel實(shí)例,DeviceMonitor在對每個(gè)設(shè)備進(jìn)行監(jiān)控之前需要先和ADB服務(wù)器建立鏈接
- mDevices: 代表一個(gè)安卓設(shè)備的Device實(shí)例組成的一個(gè)列表。注意這個(gè)Device在整個(gè)MonkeyRunner框架中非常的重要,如前面所述,它基本上可以被看成是真實(shí)安卓設(shè)備在PC端的一個(gè)代理,很多發(fā)送給ADB服務(wù)器的命令最終都是通過它發(fā)送出去的。DeviceMonitor監(jiān)控線程一旦發(fā)現(xiàn)新設(shè)備就會(huì)建立一個(gè)Device實(shí)例并放到mDevices列表里面,反之,如果一個(gè)設(shè)備被移除,就會(huì)從mDevices列表中移除
- start: 一個(gè)默認(rèn)權(quán)限的方法,所以可以被同一個(gè)ddmlib包里面的AndroidDebugBridge調(diào)用。它的作用是啟動(dòng)設(shè)備列表監(jiān)控線程,線程循環(huán)主體在下面描述的deviceMonitorLoop方法里面
- getDevices: 返回上面的mDevices設(shè)備。MonkeyRunner類的waitForConnection方法在建立與設(shè)備的連接時(shí),最終會(huì)調(diào)用到這個(gè)方法來獲得所有設(shè)備并根據(jù)設(shè)備序列號找到目標(biāo)設(shè)備去連接
- deviceMonitorLoop: 向ADB服務(wù)器發(fā)送”host:track-devices”設(shè)備監(jiān)控命令來循環(huán)獲取最新的字串類型的設(shè)備列表,這個(gè)命令類似于在命令行發(fā)送”adb devices”來獲得當(dāng)前連接的設(shè)備列表,但是不同的地方是該監(jiān)控命令發(fā)送給ADB服務(wù)器后,ADB服務(wù)器會(huì)周期性的更新設(shè)備列表然后主動(dòng)發(fā)送回來。每個(gè)循環(huán)完成后,如果發(fā)現(xiàn)ADB服務(wù)器有數(shù)據(jù)過來,都會(huì)調(diào)用下面的processIncomingDeviceData方法來作更新mDevices設(shè)備列表等事宜
- sendDeviceListMonitoringRequest:上面的deviceMonitorLoop方法調(diào)用來往ADB服務(wù)器發(fā)送”host:track-devices”設(shè)備列表監(jiān)控命令的方法
- processIncomingDeviceData:上面的deviceMonitorLoop方法在發(fā)現(xiàn)ADB服務(wù)器有數(shù)據(jù)過來的時(shí)候會(huì)調(diào)用這個(gè)方法來從與ADB服務(wù)器連接的mMainAdbConnection這個(gè)SocketChannel中把最新的字串類型設(shè)備列表讀出來,然后為每個(gè)設(shè)備實(shí)例化一個(gè)Device實(shí)例并將這些實(shí)例放到一個(gè)列表中,傳送給下面的updateDevices方法來處理
- updateDevices: 在收到上面processIncomingDeviceData發(fā)送過來的最新的Device類型的設(shè)備列表后,updateDevices會(huì)根據(jù)當(dāng)前持有的mDevices設(shè)備列表來檢查究竟哪些設(shè)備是新增加進(jìn)來的,哪些是被移除掉的,哪些是狀態(tài)改變了的來作相應(yīng)的處理:
- 新設(shè)備: 將該設(shè)備加入到DeviceMonitor維護(hù)的mDevices設(shè)備列表里面,并調(diào)用下面的startMonitoringDevice來為該設(shè)備的每個(gè)可調(diào)試應(yīng)用進(jìn)程建立一個(gè)監(jiān)控線程來監(jiān)控該VM進(jìn)程
- 設(shè)備變成ONLINE狀態(tài): 將mDevices設(shè)備列表里面對應(yīng)的設(shè)備設(shè)置成ONLINE狀態(tài),并調(diào)用下面的startMonitoringDevice來為該設(shè)備的每個(gè)可調(diào)試應(yīng)用進(jìn)程建立一個(gè)監(jiān)控線程來監(jiān)控該VM進(jìn)程
- 設(shè)備從ONLINE變成其他狀態(tài):將mDevices設(shè)備列表里面對應(yīng)的設(shè)備設(shè)置成對應(yīng)狀態(tài)?
- 移除設(shè)備: 將該設(shè)備從當(dāng)前設(shè)備列表mDevices中移除掉
- startMonitoringDevice: 獲得對應(yīng)設(shè)備中的所有可調(diào)試VM進(jìn)程的PID列表(可調(diào)試進(jìn)程指的是DalvikVM中每個(gè)啟動(dòng)了JDWP線程讓DDMS等調(diào)試工具連接的進(jìn)程),連接上每個(gè)VM的調(diào)試端口并建立對應(yīng)的客戶端監(jiān)控線程來監(jiān)控該進(jìn)程。因?yàn)榭蛻舳藱C(jī)器下層的JDWP相關(guān)的代碼主要是給DDMS等監(jiān)控調(diào)試工具使用的,所以本書不會(huì)往下作深入分析
- sendDeviceMonitoringRequest: startMonitoringDevice方法調(diào)用本方法來獲得指定設(shè)備可調(diào)試的所有進(jìn)程的PID,其實(shí)發(fā)送的就是”track-jdwp“命令
有了以上的基本認(rèn)識后,我們繼續(xù)往下分析其代碼實(shí)現(xiàn)。AndroidDebugBridge啟動(dòng)起來后,下一步就是把這個(gè)ADB實(shí)例傳到DeviceMonitor來去監(jiān)測所有連接到adb服務(wù)器也就是pc主機(jī)端的android設(shè)備的狀態(tài):
70?? DeviceMonitor(AndroidDebugBridge server)
?71?? {
?72???? this.mServer = server;
?73
?74???? this.mDebuggerPorts.add(Integer.valueOf(DdmPreferences.getDebugPortBase()));
?75?? }
代碼8-4-1 DeviceMonitor構(gòu)造函數(shù)
?
保存好AndroidDebugBridge實(shí)例后,下一步就是繼續(xù)AndroidDebugBridge啟動(dòng)函數(shù)start()啟動(dòng)DeviceMonitor設(shè)備監(jiān)控線程:
79?? void start()
?80?? {
?81???? new Thread("Device List Monitor")
?82???? {
?83?????? public void run() {
?84???????? DeviceMonitor.this.deviceMonitorLoop();
?85?????? }
?86???? }.start();
?87?? }
代碼8-4-2 DeviceMonitor - start
?
轉(zhuǎn)載于:https://www.cnblogs.com/poptest/p/5089487.html
總結(jié)
以上是生活随笔為你收集整理的老李推荐: 第8章4节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 1...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习node js 之微信公众帐号接口开
- 下一篇: php读取html文件(或php文件)的