Android測試工具之強大的adb工具
Android除錯橋接(adb)是電腦與裝置(Android模擬器或者Android裝置)進行通訊的通用命令列工具。adb提供了各種各樣的裝置命令,包括安裝、除錯app以及在Unix shell中可以使用的大多數命令。adb是一個客戶端-服務端模式的程式,有以下三個元件:
1、客戶端,傳送命令。客戶端執行在開發機上,我們可以從命令列終端執行adb命令調啟客戶端程式。
2、守護程序(adbd),執行在裝置上的後臺程式。
3、服務端,管理客戶端和守護程序之間的通訊,它作為後臺程序執行在我們的開發機上。
abb工具包含在Android SDK平臺工具包中(android_sdk/platform-tools/
adb是怎樣工作的?
執行adb客戶端的時候,首先會檢測adb服務端程序是否已經執行。如果服務端程序沒有執行,它會主動開啟服務端程序;如果服務端程序已經執行,它將會繫結本地TCP埠5037,同時監聽從客戶端傳送出去的命令--所有的adb客戶端使用5037埠和adb服務端通訊,然後服務端和所有可連線裝置建立連線。
但對於模擬器而言,服務端程序將會掃描5555~5585之間的奇數作為埠,也就是最多可以連線16個模擬器。還有一點,服務端找到守護程序後就會連線掃描到的可用埠,不過從原理上講,每個模擬器使用一對順序的埠---一個偶數埠用語控制檯連線,一個奇數埠用於adb連線。例如:
Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557
... ...
一旦服務端連線上了可連線的所有裝置,你就可以使用adb命令訪問這些裝置,還可以開啟多個adb客戶端來控制多個裝置的操作,adb的強大之處可見一斑。
adb安裝
brew cask install android-platform-tools
檢視已連線裝置
adb devices
在裝置上開啟adb除錯
使用adb連線到裝置需要通過USB介面,我們必須開啟裝置系統--設定--開發者選項中的USB除錯功能。在Android4.2以後的版本中,開發者選項是預設隱藏的。為了讓它顯示,需要從'設定'--'關於手機'中找到'構建版本號
怎麼知道通過USB連線上了自己的裝置呢?在命令列終端使用'adb devices'(當然要設定android_sdk/platform-tools/目錄的環境變數),如果連線上裝置,將會在終端下看到連線成功的資訊。
注意: 在連線Android 4.2.2以上的裝置中,系統將出現一個是否允許在當前開發機上開啟除錯功能的對話方塊,這是一種保護使用者裝置的安全機制。
通過Wi-Fi連線到裝置
一般adb通過USB連線到裝置,但是我們使用USB初始化某些設定之後,也可以通過Wi-Fi進行連線。如果你正在開發Android Wear,應該去看debugging an Android Wear app上的指南,指南里面有相關特殊指令使用adb 與Wi-Fi和藍芽通訊。如下描述Wi-Fi連線到裝置的操作:
- Android裝置和開發主機連線到同一Wi-Fi網路中,但不是所有的接入點都可以使用,有時你可能需要在開啟了防火牆的訪問點上配置訪問點支援adb。
- 如果Android裝置連線到Android穿戴裝置上,關閉Android 裝置上的藍芽配對。
- 使用USB線纜連線Android裝置到開發主機上。
- 設定目標裝置使用TCP/IP連線到監聽埠5555上。
adb tcpip 5555
- 從目標裝置斷開USB連線。
- 找到Android裝置的IP地址。
- adb連線到android裝置的IP地址。
adb connect device_ip_address
- 檢視開發機是否連線到Android裝置。
$ adb devices List of devices attached device_ip_address:5555 device
如果adb連線中斷:
- 檢查你的開發機是否和Android裝置在同一Wi-Fi網路中
- 開發機執命令
adb connect
進行重連。 - 仍然不工作的話, 關閉並重新開啟服務端管理程式:
adb kill-server
add start-server
裝置查詢
在傳送adb命令之前,一般先要檢查連線到adb端的裝置是否正常,如下:
adb devices -l
在響應的資訊中,adb將列印每個裝置的狀態資訊:
- 序列號: 能被adb埠號唯一識別裝置的字串,例如:
emulator-5554
- 裝置連線狀態包括:
offline
: 裝置不能連線到adb,沒有響應。device
: 裝置連線到了adb服務端。但在裝置系統正在啟動的過程中不一定能正確反映它的狀態。no device
: 沒有裝置連線
- 描述: 如果加上了
-l
選項,devices命令將返回裝置資訊。這在有多個裝置連線的情況下是比較有用的。
下面的例子展示了The following example shows the devices
command and its output. There are three devices running. The first two lines in the list are emulators, and the third line is a physical device that is attached to the computer.
$ adb devices List of devices attached emulator-5556 device product:sdk_google_phone_x86_64 model:Android_SDK_built_for_x86_64 device:generic_x86_64 emulator-5554 device product:sdk_google_phone_x86 model:Android_SDK_built_for_x86 device:generic_x86 0a388e93 device usb:1-1 product:razor model:Nexus_7 device:flo
模擬器不再adb devices產生的列表中
adb devices
在個別情況下的輸出是不會顯示模擬器執行狀況的,即使模擬器在開發機上是可見的,這樣的情形在如下條件下產生:
- adb服務端沒有執行;
- 使用
emulator
命令中的-port
或者-ports
選項的埠是介於5554和5584之間的奇數值; - 選擇的奇數埠空閒,使得在連線模擬器的時候選擇了奇數埠;或者奇數埠處於繁忙狀態,模擬器切換到其他埠(就像第二條所描述的那樣);
- 模擬器啟動後adb服務端還沒有啟動。
避免這種條件的一種方法是:讓模擬器自己選擇埠,同時不要立刻執行超過16個模擬器;避免這種情況的另外一種方法是:總是在執行emulator命令之前啟動adb服務端。為什麼呢?
情形1:在接下來的命令執行序列中,直接使用adb
devices
命令啟動adb服務端,並沒有出現模擬器的裝置資訊列表。
那麼我們要做的是,使用下面的命令停止adb服務端。從系統中獲取一個有效的Android虛擬裝置名稱(要想知道系統擁有的Android虛擬裝置名稱,執行emulator -list-avds即可),併為它分配一個埠。
$ adb kill-server $ emulator -avd Nexus_6_API_25-port 5555 $ adb devices List of devices attached * daemon not running. starting it now on port 5037** daemon started successfully *
情形2: 在接下來的命令執行序列中,adb devices
顯示了裝置列表資訊,因為我們先啟動了adb服務端。
我們看到了執行adb devices命令的輸出中顯示了模擬器資訊,因為停止adb服務端後就接著啟動了adb服務端,如下所示:
$ adb kill-server $ emulator -avd Nexus_6_API_25-port 5557 $ adb start-server $ adb devices List of devices attached emulator-5557 device
傳送命令到指定裝置
如果多個裝置同時執行,在執行adb命令的時候你必須指定目標裝置。制定到目標裝置後,使用devices命令獲取目標裝置的序列號。一旦獲取了序列號,使用adb命令的 -s
選項指定到序列號。如果要執行很多adb命令,可以設定$ANDROID_SERIAL
環境變數進行替換。
$ adb devices List of devices attached emulator-5554 device emulator-5555 device $ adb -s emulator-5555 install helloWorld.apk
注意: 多個裝置同時執行的時候,如果不指定目標裝置, adb會產生一個錯誤。
如果有多個Android裝置可用,但只有一個模擬器,那麼使用-e
選項傳送命令到模擬器;如果有多個模擬器,但只有一個裝置,那麼使用-d
選項命令到Android裝置。
安裝App
使用adb命令在模擬器上安裝一個APK或者使用安裝命令install連線裝置:
adb install path_to_apk
設定埠轉發
你可以使用 forward
命令設定任意的埠轉發,但需要指定從主機埠到裝置上不同埠的轉發請求 :
adb forward tcp:6100 tcp:7100
如下設定主機轉發埠6100到local:logd:
adb forward tcp:6100 local:logd
裝置檔案的匯入匯出
使用 pull
和 push
命令從裝置匯入匯出檔案,它們不像 install
命令, 只能匯出APK檔案到指定的位置:
adb pull remote local
匯入檔案或目錄到裝置的命令格式:
adb push local remote
從開發機匯入檔案到裝置的實際操作如下:
adb push foo.txt /sdcard/foo.txt
停止adb服務端
在某些情況下,可能需要終止adb服務端程序,然後重啟才能解決問題。
停止adb服務端,使用adb kill-server
命令,然後使用其他adb命令重啟服務端程序。
adb命令引用
可以從開發機命令列或者指令碼傳送adb命令,如下:
adb [-d | -e | -s serial_number] command
如果只有一個模擬器執行或者一個裝置連線,adb命令會預設傳送目標。如果多個模擬器同時執行或者多個裝置連線,需要使用-d
, -e
,
或者-s
選項指定目標裝置。
通過adb help命令檢視選項及命令,如下:
~$ adb help
傳送shell命令
可以通過adb傳送shell命令, 像下面這樣使用 shell
命令:
adb [-d |-e | -s serial_number] shell shell_command
或者在裝置上建立一個遠端shell:
adb [-d | -e | -s serial_number] shell
如果想退出遠端shell, 按 Control + D 或者 輸入 exit
.
shell命令的可執行檔案儲存在裝置檔案系統/system/bin/中。
呼叫 activity manager (am
)
在adb shell中, 可以使用activity manager工具傳送命令執行各種各樣的系統動作。比如開始一個activity,強制停止一個程序,廣播一個Intent,改變裝置螢幕屬性,等等。在shell中的語法是:
am command
你可以通過adb直接傳送一個activity manager命令而不需要進入遠端shell,例如:
adb shell am start -a android.intent.action.VIEW
$ adb shell am
呼叫 package manager (pm
)
在adbshell中,可以使用package manager工具傳送命令執行動作或查詢安裝在裝置上的app, 在shell中的語法是:
pm command
你可以通過adb直接傳送一個package manager命令而不需要進入遠端shell,例如:
adb shell pm uninstall com.example.MyApp
$ adb shell pm
獲取截圖
screencap命令用於獲取裝置顯示螢幕截圖。 在shell中的語法是:
screencap filename
輸入如下內容,從命令列截圖:
adb shell screencap /sdcard/screen.png
這裡又一個擷取影象的例子, 使用adb shell 從裝置截圖並拷貝到本地:
$ adb shell [email protected] $ screencap /sdcard/screen.png [email protected] $ exit $ adb pull /sdcard/screen.png
錄製視訊
screenrecord命令是一個社screenrecord命令用於獲取裝置視訊錄製,支援系統版本Android 4.4 (API level 19) 以上,錄製視訊格式為MP4.
注意: 在視訊檔案中不包含音訊檔案.
開發者可以錄製視訊作為宣傳使用,在shell中的語法是:
screenrecord [options] filename
adb shell screenrecord /sdcard/demo.mp4
按下Control + C停止視訊錄製, 否則錄製超過3分鐘才能自動停止,或者使用--time-limit選項設定時間限制。
錄製和獲取檔案到本地的命令如下:
$ adb shell [email protected] $ screenrecord --verbose /sdcard/demo.mp4 (press Control+ C to stop) [email protected] $ exit $ adb pull /sdcard/demo.mp4
screenrecord實用工具可以錄製任何解析度和bit率的視訊,適配裝置顯示的寬高比,最大時長為3分鐘。
在使用screenrecord實用工具時,要知道它的一些限制:
1、一些裝置時無法錄製它原始顯示解析度的,如果出現了問題,試著降低錄製解析度。
2、在錄製的時候,不允許旋轉螢幕,否則錄製的視訊影象會被截掉一部分。
screenrecord命令的使用。連上裝置,使用如下命令檢視:
$ adb shell screenrecord