【轉載】Android 工具-adb原理

Android 開發中, adb 是開發者常用的工具,是 Android 開發者必須掌握的。html

Android Debug Bridge,Android 調試橋接器,簡稱 adb ,該工具位於 <sdk>/platform-tools/ 目錄下,其源碼位於 <path-to-sourcecode>/system/core/adb 目錄下,是用於管理模擬器或真機狀態的萬能工具。 adb 採用了客戶端-服務器模型,包括三個部分:linux

  1. 客戶端部分,運行在開發用的電腦上,能夠在命令行中運行adb命令來調用該客戶端,像 DDMS 這樣的 Android 工具也能夠調用 adb 客戶端。
  2. 守護進程部分,運行於模擬器或手機的後臺。
  3. 服務端部分,是運行在開發用電腦上的後臺進程,用於管理客戶端與運行在模擬器或真機的守護進程通訊。

adb 工具模型示意圖以下:
041521549671304android

adb 的工做原理

當啓動 adb 客戶端時,客戶端首先檢查 adb 服務端進程是否運行,若是沒有運行,則啓動服務端。當服務端啓動時,它會綁定到本地的 TCP5037 端口,而且監遵從 adb 客戶端發來的命令——全部 adb 客戶端都使用 5037 端口與 adb 服務端通訊。shell

接下來服務端與全部正在運行的模擬器或手機鏈接。它經過掃描 5555-5585 之間的奇數號端口來搜索模擬器或手機,一旦發現 adb 守護進程,就經過此端口進行鏈接。須要說明的是,每個模擬器或手機使用一對有序的端口,偶數號端口用於控制檯鏈接,奇數號端口用於 adb 鏈接,例如:緩存

Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557 ...

即若是模擬器與 adb 在 5555 端口鏈接,則其與控制檯的鏈接就是 5554 端口。服務器

當服務端與全部的模擬器創建鏈接以後,就可使用 adb 命令來控制或者訪問了。由於服務端管理着鏈接而且能夠接收到從多個 adb 客戶端的命令,因此能夠從任何一個客戶端或腳原本控制任何模擬器或手機設備。網絡

補充less

  1. 使用 adb 命令調試須要手機開啓 開發者模式 下的 USB 調試,在 Android 4.2 及更高的版本中,開發者選項默認是隱藏的,你能夠去 設置——>關於手機 ,而後連續點擊七次版本號便可。返回上層就能夠在底部看見 開發者模式 了。固然有些定製的 ROM 開啓方式會有點不同,這個就要去問 ROM 的開發者了。
  2. 關於 USB 調試與計算機的 RSA 密鑰指紋配對。Google 官方原文以下:socket

    When you connect a device running Android 4.2.2 or higher to your computer, the system shows a dialog asking whether to accept an RSA key that allows debugging through this computer. This security mechanism protects user devices because it ensures that USB debugging and other adb commands cannot be executed unless you're able to unlock the device and acknowledge the dialog. This requires that you have adb version 1.0.31 (available with SDK Platform-tools r16.0.1 and higher) in order to debug on a device running Android 4.2.2 or higher.tcp

大意就是,你想使用 USB調試 就得啓用 USB調試 模式下的 RSA密鑰指紋。否則我就不給你用。

  1. 關於使用真機調試的更多信息可參考:Run Apps on a Hardware Device

adb 用法

查詢模擬器或手機狀態

瞭解 adb 服務端鏈接的模擬器或手機能夠幫助更好的使用 adb 命令,這能夠經過 devices 命令來列舉當前鏈接的設備:

adb devices

執行結果是 adb 爲每個設備輸出如下狀態信息:

序列號(serialNumber):由 adb 建立用於惟一標識設備的字符串,格式是 <設備類型>-<端口號>,例如: emulator-5554

鏈接狀態(state),其值是多是下面的任意一種:

offline — 未鏈接或未響應

device — 表示設備已經鏈接到服務端。但須要注意的是,這個狀態並不表示 Android 系統已經徹底啓動起來而且可操做,由於系統在啓動的過程當中就已經鏈接 adb ,但這個狀態是正常的可操做狀態。

no device - 表示沒有任何設備鏈接(樓主測試過程當中沒有碰到過 no device 的狀況,沒鏈接設備就沒任何輸出)

每個設備的輸出形如:

[serialNumber] [state]

下面是 adb devices 命令和其執行結果:

$ adb devices
List of devices attached 
emulator-5554  device
emulator-5556  device
emulator-5558  device

若是沒有模擬器或手機在運行,運行 adb devices 命令的執行結果以下:

$ adb devces
List of devices attached

操做指定模擬器或手機

若是有多個模擬器或手機正在運行,當使用 adb 命令的時候就須要指定目標設備,這能夠經過使用 -s 選項參數實現,用法以下:

adb -s <serialNumber> <command>

你可使用 adb 命令指定序列號在特定的設備上執行命令,這裏能夠先使用前面提到的 adb devices 命令查詢設備的序列號信息。

例如:

adb -s emulator-5556 install helloWorld.apk

須要注意的是,若是使用了 -s 而沒有指定設備的話, adb 會報錯。

補充
這是 Google 官方給出在多設備的狀況下,不用 -s 參數指定目標設備的快捷方式,原文以下:

If you have multiple devices available (hardware or emulated), but only one is an emulator, simply use the -e option to send commands to the emulator. Likewise if there's multiple devices but only one hardware device attached, use the -d option to send commands to the hardware device.

大意就是:若是你有多個設備,即既有模擬器,又有真機,可是模擬器只有一個,那麼你可使用 -e 參數想模擬器發送命令,用法以下:

$ adb -e install helloWorld.apk
//同理,若是有多個設備,但只有一個真機,可使用以下命令快速發送命令
$ adb -d install helloWorld.apk

安裝應用

使用 adb install 命令能夠從開發用電腦中複製應用程序而且安裝到模擬器或手機上,adb install 命令必須指定待安裝的.apk文件的路徑:

adb install [-lrtsdg] <path_to_apk>
(-l: 鎖定該程序)
(-r: 從新安裝該程序,保留應用數據)
(-t: allow test packages)
(-s: 將應用安裝到 SD卡,不過如今手機好像都沒有 SD卡 了吧)
(-d: 容許降版本號安裝,固然只有 debug 包才能使用)
(-g: 安裝完默認授予全部運行時權限,這個應該對 Android 6.0 及以後的版本纔有效吧)

更多關於建立 apk 文件可參考:Build And Running

卸載應用

既然有安裝應用的命令,那固然有卸載應用的命令。卸載應用命令的格式以下:

//<package> 表示要卸載應用的包名
adb uninstall [-k] <package>
(-k:不刪除程序運行所產生的數據和緩存目錄)

端口轉發

使用 adb forward 命令轉發端口 — 將特定端口上的請求轉發到模擬器或手機的不一樣的端口上。下例是從 6100端口 轉到 7100端口 :

adb forward tcp:6100 tcp:7100

也可使用UNIX命名的socket標識:

adb forward tcp:6100 local:logd

補充:關於 adb forward 命令的做用不是很明白,網上搜了下,大部分文章都是轉載了 淺析 adb 命令 - adb forward ,不知道這是否是原文,反正看不得不是很明白。有哪位大神能跟我講講嘛?

與模擬器或手機傳輸文件

使用 adb 命令 pull 和 push 能從 Android 設備拷貝或複製文件到 Android 設備。跟 install 命令不一樣,pull 和 push 命令容許拷貝和複製文件到任何位置。

從模擬器或手機拷貝文件或文件夾(包括文件夾的子目錄)

adb pull [-a] <remote_path> <local_path>
(-a:保留文件時間戳及屬性)

將文件或文件夾(包括文件夾的子目錄)拷貝到模擬器或手機

adb push <local_path> <remote_path>

好比,我想把桌面的 log.txt 複製到手機的 dev 目錄下,則命令以下:

$ adb push /Users/littlejie/Desktop/log.txt /dev

有時候,使用該命令複製文件到手機或從手機複製文件,會碰到以下提示:

failed to copy 'log.txt' to '/dev/log.txt': Permission denied

備註: Permission denied 這個問題之前在使用 Windows 系統的時候碰到過,如今轉 Mac 後就沒有再遇到,難道是我打開方式不對嘛?再補充一點, Mac 上我運行 adb root 命令真的有點一頭霧水,由於居然提示:

$ adb root
adbd is already running as root

這是由於當前用戶沒有相應的權限或者是 /dev 目錄不可寫。解決方法以下:

//方法一
//已 root 權限啓動 adb 服務
$ adb root
//adb remount (從新掛載系統分區,使系統分區從新可寫)
$ adb remount
//將文件複製到 /dev 目錄下
$ adb push /Users/littlejie/Desktop/log.txt /dev
//方法二:修改文件的讀寫權限
$ adb shell
# su
# chmod 777 /dev

關於 Linux 下文件權限的更多內容請參考:linux系統64四、75五、777權限詳解

adb shell

這裏簡單講一下 adb shell 的使用,由於 adb shell 的用法太多,功能太強,徹底能夠專門分出一篇文章來記錄~不出意外,下週應該能寫完~有興趣的同窗能夠本身先去看 Google 的官方文檔:ADB Shell Commands

adb shell 有兩種使用方式,一種是不進入 remote shell 直接執行命令行,格式以下:

adb [-d|-e|-s <serialNumber>] shell <shell_command>

還有一種是,進入模擬器或手機的 remote shell 執行,格式以下:

adb [-d|-e|-s <serialNumber>] shell

開啓或關閉 adb 服務

在某些狀況下須要重啓 adb 服務來解決問題,好比 adb 無響應。這時你能夠經過 adb kill-server 來實現這一操做。

以後,經過 adb start-server 或者任意 adb 命令來重啓 adb 服務。

$ adb kill-server
$ adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *

$ adb kill-server
$ adb devices
List of devices attached
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
emulator-5556   device
emulator-5554   device

無線調試

平時咱們都是使用 USB調試,可是如今也支持經過 WIFI 進行調試了。使用方式以下:

  1. 首先,你要將 Android 設備和 裝有 adb 的電腦鏈接到同一 Wi-Fi 網絡。其次,你須要配置好防火牆,不然頗有可能致使 Wi-Fi 調試不能使用。
  2. 使用 USB數據線 將手機鏈接到電腦。
  3. 設置目標設備監聽 5555端口 的 TCP/IP 鏈接。

shell $ adb tcpip 5555

  1. 斷開手機與電腦的 USB 鏈接。
  2. 查看手機的 IP地址 。例如,在 Nexus 設備上,你能夠經過以下方式查看: 設置——>關於手機——>狀態——>IP地址。在 Androir Wear 上,你能夠經過以下方式查看:設置——>Wi-Fi設置——>高級——>IP地址
  3. 經過 IP 鏈接手機

shell adb connect <device_ip_address>

  1. 確認手機是否鏈接到電腦上

shell $ adb devices List of devices attached <device-ip-address>:5555 device

經過以上步驟,就能夠開心的享用 WiFi 調試了。若是沒有正常鏈接,能夠按照下面的步驟檢查:

  1. 檢查電腦和手機是否還在同一個 WiFi 網絡下
  2. 從新執行一次 adb connect <device_ip_address> 命令
  3. 重啓 adb 服務,而後重頭再來
  4. 檢查是不是防火牆的設置問題

這是一篇關於 Android 設備 USB調試 和 WiFi調試 相互切換 的博文,博主寫了一個腳原本實現這個過程,有興趣的同窗能夠去看看。

補充

  • 獲取設備序列號

shell $ adb shell emulator-5554

  • 查看 bugreport 報告

shell //直接在終端輸出 $ adb bugreport //將 bugreport 輸出到指定文件 $ adb bugreport > file_path
adb bugreport 這個命令很是簡單,可是在實際應用中很是有用,它會輸出從開機以後詳細的 dumpsys 、 dumpstate 和 logcat 信息,是一份完整的日誌記錄。對分析用戶行爲、異常信息、系統狀態有很大的參考做用。通常咱們會把 bugreport 導出到電腦上分析。
bugreport 的詳細使用能夠參考 Baniel01 的這篇 Android adb bugreport工具分析和使用 文章,裏面有很詳細的介紹。

  • 查看設備的 log

shell $ adb logcat

  • 查看 adb 的幫助
    這個命令很簡單,可是也很實用,若是你不知道該使用哪一個命令,那麼使用 adb 幫助命令你能查看到大部分 adb 命令的做用和使用方法。

shell $ adb help

  • 重啓手機
    有時候,手動關機太麻煩,那就來個命令行吧~

shell adb reboot

  • 以 root 權限開啓 adb 守護進程

shell //此命令會重啓守護進程 $ adb root //不以 root 權限開啓 adb 守護進程 $ adb unroot

總結

以上就是 adb 命令的常見用法,大部分翻譯自 Android Debug Bridge ,其中加了一些我的總結。有些不經常使用的 adb 命令沒有介紹,更多 adb 用法請見:Adb Command Summary。文中若有紕漏,歡迎你們留言指出。

微博:厲聖傑

相關文章
相關標籤/搜索