文章多處連結需要科學上網
本文按順序主要講解了ADB的原理,使用Wi-Fi連線裝置,ADB常用命令,在Java程式碼中執行shell命令,使用ddmlib進行擴充套件。
ADB的原理
參考 官方文件
ADB(Android Debug Bridge)是一個通用的命令列工具,能讓你和模擬器或連線的Android手機通訊。
ADB的結構是一個client-server的結構,包含3個部分:
-
A Client : 傳送命令。客戶端在你開發的PC上執行,當你在shell裡使用Adb命令的時候就會開啟一個client。(其實你的shell就是一個client)
-
A daemon : 在裝置上執行命令。守護程式在裝置上後臺執行。(也就是一個叫做aabd的東西,執行在Andriod裝置的底層)
-
A server : 管理客戶端(client)和守護程式(daemon)的連線。server在開發app的PC上後臺執行。
你可以在 /platform-tools 找到adb工具
ADB是如何工作的?
當你開啟一個adb client,client會首先檢查adb server是否執行,如果沒有的話先啟動一個adb server,當server啟動後,server預設繫結到本地(PC)的TCP埠5037(這個埠號可以設定,後文有述)並開始監聽從client傳送的命令。(所有的adb client都會用5037埠和server通訊)
然後server會建立和所有正在執行的裝置或模擬器的通訊連線。server通過掃描5555至5585之間的奇數號埠查詢裝置(這就是說裝置所使用的埠號一定是5555-5585之間的奇數),如果server找到了一個守護程式daemon(執行在裝置上的),那麼server就會在這個埠建立一個連線(server是client和daemon的中間的橋樑)
注意:每一個裝置需要一對連續的埠號,奇數埠號用來建立adb連線,偶數埠號用於控制檯連線(原文是console connections,據我理解應該是指 控制模擬器用的console連線)
像這樣:
Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557
and so on...
複製程式碼
上一個結構圖:
*上面的圖片來自於一篇很早比較詳細的文章 android adb adbd analyse *
有可能有人會問:5555-5585的奇數埠號是指定裝置的,那麼裝置有沒有上限呢?
答案是沒有,原因如下:
- 1.adb可以使用WiFi連線,也就是通過無線網路連線。下文會講無線連線如何使用
- 2.adb可以為adb server指定埠號,指定埠號後可以開啟多個server(不過Android Studio在除錯程式時只識別5037埠的server)。
像這樣:
可以通過大寫的-P指定埠號,指定埠號後會開啟一個新的server,這樣的缺點就是,如果以後想檢視5038埠server的一系列操作,比如檢視連線的裝置也必須加 -P 5038,否則檢視的只是5037的server連線的裝置。 如果之前已經開啟了5037的server,那麼現在你的PC上現在已經有了兩個server,這裡注意,你的裝置只能和其中一個server通訊。
正式因為上面結構圖的結構,才能使得adb能夠通過wifi進行連線。
使用wi-fi連線的使用方法:
1.將你的Android裝置和你的開發機器連線到同一個Wi-Fi網路環境下,記住是同一個。不是所有的無線節點都可以匹配,你也許需要使用支援adb的防火牆配置。(我將防火牆關閉了)
2.將你的裝置和電腦通過USB連線
3.將你的手機設定成在埠5555監聽TCP/ip連線(在PC上執行,埠號自己指定)
$ adb tcpip 5555
4.斷開USB資料線
5.檢視你的手機的IP地址(在手機連線的WiFi網路的心裡了能看到,每個手機的配置不一樣~)
6.通過指定IP地址進行連線
$ adb connect <device-ip-address>
7.看看效果吧,確定你的電腦是否已經連線上你的手機了
$ adb devices
List of devices attached
<device-ip-address>:5555 device
複製程式碼
如果沒有連線上
- 確定連在同一個wifi環境下
- 重試
adb connect
或重啟adb serveradb kill-server
&adb start-server
熟悉Android Studio的人應該知道有一個叫做 ADBWIFI 的除錯外掛,裡面用到的也是這些命令原理,剛開始我還覺得能自己開發一款Android Studio的外掛很神奇,其實你開啟那個連結琢磨琢磨,你也可以。裡面用到了ddmlib這個jar包,文章的最後簡要介紹一下(感興趣的話可以好好研究。。)
ADB常用命令
語法:adb [-d|-e|-s <serialNumber>] <command>
如果你只連線一個物理裝置,可以通過-d快速指定物理裝置,如果你連線了只連線了一個模擬器,可以通過-e快速指定模擬器。
- devices : 連線的裝置列表,你可以看到serialNumber
- help : 命令幫助
- version : adb版本
- logcat [option] [filter-specs] :在螢幕上列印log,如果這個命令不會可以輸入
adb logcat --help
檢視怎麼使用 - bugreport : 列印dumpsys, dumpstate, logcat的資訊,為了報告bug,類似
adb bugreport > xxx.log
- start-server : 開啟一個adb server
- kill-server : 關閉adb server
- install :安裝apk(specified as a full path to an .apk file))
- pull : 從你裝置的remote拷貝檔案到你PC上的local
- push : 從你PC上的local拷貝檔案到你裝置的remote
- forward : 將你本地的特定埠的資訊轉發給你裝置的remote埠上。 like this:
adb forward tcp:6100 tcp:7100 PC上所有6100埠通訊資料將被重定向到手機端7100埠server上 adb forward tcp:6100 local:logd PC上所有6100埠通訊資料將被重定向到手機端UNIX型別socket上
- get-serialno : 得到裝置的序列號,其實就是devices的結果的前半部分
- get-state : 得到裝置的狀態[offline, device, no device]
- wait-for-device : 直到裝置online之後才會繼續執行,否則阻塞執行。like this:
adb wait-for-device install <app>.apk
安裝apk需要裝置啟動之後才能執行,和其他adb命令配合使用
jdwp 和 ppp兩個命令沒搞清楚如何使用,歡迎知道的告訴我,互相學習,感謝 :)
adb shell
shell命令執行在android的裝置上,命令的二進位制檔案在手機的/system/bin/...
下
語法:adb [-d|-e|-s <serialNumber>] shell <shell_command>
am
在shell命令下,你可以通過activity manager 工具(am)執行系統操作,包括開始一個activity, 強制關閉程式,廣播intent,設定裝置螢幕引數等。
語法是am <command>
,eg : adb shell am start -a android.intent.action.VIEW
內容比較多,建議翻牆詳細看,原文挺簡單的,我就不翻譯了 :)
和am搭配使用的有:
Comand | Description |
---|---|
start [options] | Start an Activity specified by |
startservice [options] | Start the Service specified by . |
force-stop | Force stop everything associated with (the app's package name). |
kill [options] | Kill all processes associated with (the app's package name). This command kills only processes that are safe to kill and that will not impact the user experience. |
pm
在shell命令下,你可以通過package manager(pm)執行和包相關的操作。語法是pm <command>
,eg : adb shell pm uninstall com.example.MyApp
,和am類似,這裡就不一一展開了,需要請看官方文件。
截圖
像這樣eg: $ adb shell screencap /sdcard/screen.png
你還可以這樣,截圖後從手機copy一份。
$ adb shell
shell@ $ screencap /sdcard/screen.png
shell@ $ exit
$ adb pull /sdcard/screen.png
複製程式碼
錄屏
僅支援 Android 4.4 (API level 19)及以上
Note: Audio is not recorded with the video file. 僅僅是畫面而已
還有很多引數可以設定,這裡不展開
eg: $ adb shell screenrecord /sdcard/demo.mp4
其他
dumpsys [options]
meminfo 顯示記憶體資訊
cpuinfo 顯示CPU資訊
account 顯示accounts資訊
activity 顯示所有的activities的資訊
window 顯示鍵盤,視窗和它們的關係
wifi 顯示wifi資訊
and so on
複製程式碼
eg:adb shell dumpsys meminfo [packageName]
By the way....你可以在java程式碼中執行這些命令,並將結果寫到檔案中,然後將檔案傳送到你的伺服器上進行分析~~
參考: Running Shell commands though java code on Android? writing dumpstate to file android
ADB擴充套件
這裡只簡單的說一些。 ADBWIFI 外掛的原始碼下載下來後你可以看到裡面有一個ddmlib的類庫,它的位置在你的android-sdk下面的/sdk/tools/lib 目錄下,這個目錄下還有ddmuilib.jar,ddms.jar等。
那麼這些工具有什麼用呢?
通過這些工具你可以在你的程式碼中
1.建立ADB
AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
複製程式碼
2.獲得ADB連線的裝置
IDevice devices[] = bridge.getDevices();
複製程式碼
3.操作裝置
device.installPackage(path, true, args); //device instance of IDevice
device.uninstallPackage(pakagename);
複製程式碼
4.執行adb命令
device.executeShellCommand(cmd, receiver);
// receiver extends MultiLineReceiver
// cmd like "dumpsys meminfo [packageName]" adb shell command
複製程式碼
是不是很酷?如果能夠再深入下去應該能發掘更多有意思的東西,感興趣的自己研究研究吧,東西挺多的 :)
可以參考 使用ddmlib實現android 效能監控 或直接閱讀 ADBWIFI 的原始碼