adb即 Android Debug Bridge 是一個通用的命令行工具,可用於經過PC端對鏈接的Android模擬器設備或鏈接至電腦的真實物理設備進行命令行操做。目前,許多軟件均會藉助 adb 工具與移動終端進行交互。這裏以 Android Studio 中帶有的 adb 工具爲例,描述與啓動 adb shell相關的步驟,從而解釋出現上述錯誤的緣由。html
Android Studio 自帶的 adb 位於C:\Users\user_name\AppData\Local\Android\Sdk\platform-tools文件夾下(即實際位置取決於Sdk的安裝目錄)。android
命令行運行adb工具shell
安裝 Android Studio 後,命令行中輸入 adb 命令(如adb -version,顯示adb的版本號)時,系統會提示找不到該命令。這是因爲 adb 工具的位置沒法被肯定,可經過如下幾種方案在命令行方式下運行 adb :服務器
(1)將 adb 工具所在目錄的路徑加入系統的 Path 環境變量中,則可在命令行的任意路徑下直接運行 adb 命令。在這裏,也就是將 C:\Users\user_name\AppData\Local\Android\Sdk\platform-tools 加入 Path 變量中;網絡
(2)切換控制檯中的路徑至 adb 工具所在路徑下,如能夠經過命令 cd C:\Users\user_name\AppData\Local\Android\Sdk\platform-tools切換至 adb 工具所在的文件夾,便可在當前命令行中直接運行 adb 命令;工具
(3)在文件管理器中,進入上述 C:\Users\user_name\AppData\Local\Android\Sdk\platform-tools 目錄,在該目錄內,按住 Shift 鍵,右鍵 -> 在此處打開命令窗口 ,在打開的窗口中能夠看到控制檯提供的路徑名稱與(1)中切換後的效果是一致的;this
沒法運行 adb shell 命令url
在完成上述操做後,運行 adb shell 命令,出現報錯信息:adb server version (26) doesn't match this client (39); killing...spa
根據查到的資料的一些說法,這一問題是因爲系統上存在兩個不同版本的 adb 工具形成的。.net
筆者在上述目錄下(屬於Android Studio的目錄)運行了命令 adb version,結果以下圖:
也就是說當前目錄下,Android Studio自帶的adb工具版本爲 1.0.39 ,猜測這就是上述報錯信息中的 client(39),相應的可能系統上還存在一個版本爲26的 adb 工具。
問題描述
筆者查閱了Android Studio官網上對 adb 工具的介紹。介紹中對 adb 的描述: 啓動一個adb 客戶端時,此客戶端首先檢查是否有已經運行的 adb 服務器進程。若是沒有,它將啓動服務器進程。當服務器啓動後,它將與本地 TCP 端口 5037 綁定,並偵遵從 adb 客戶端發送的命令。全部的 adb 客戶端均經過端口 5037 與 adb 服務器進行通訊。
經過上述描述,能夠看到既然報錯信息顯示的是adb server version(26),那當前系統中必定存在一個 adb 服務進程 , 它較之咱們運行的那個 adb 工具先開始,且版本要低於咱們使用的 adb 版本。能夠經過命令行工具查找該進程。
(1)因爲 adb 服務進程必定會佔據 5037 端口,因此首先查看當前 5037 端口被那個進程調用。命令行方式下能夠經過 netstat 命令顯示當前的網絡狀況,可經過 netstat /? 查看命令幫助。
netstat -ano | findstr "5037" //在 netstat 輸出的結果中篩選出有 5037 字符串的行,findstr命令相似於Linux下的grep
結果以下圖所示:
(2)得到上述進程 pid 對應的進程的信息。有兩種方式,經過命令行或者任務管理器。
a)打開 任務管理器 -> 詳細信息 ,經過 pid 便可定位對應的進程,可經過右鍵 -> 屬性,可查看該進程的描述信息,從而得到另外一個 adb 工具相關的信息;
b)經過命令行工具,tasklist | findstr "10044"找到對應的進程;
tasklist | findstr "xxx" //將tasklist輸出結果中帶有目標字符串的行篩選出來
其中,經過任務管理器得到的信息更詳細,能夠定位到對應的 adb 工具的目錄位置。好比 360 的軟件中,會帶有 adb 工具,而這可能會帶來 adb 工具版本的不一樣。
解決方案
解決的方法包括但不限於將以前啓動的adb服務進程刪除掉(注意要肯定對應的應用程序能夠關閉該服務),以後再啓動咱們想要的 adb 工具。
在終止了以前存在的不一樣版本的 adb 服務進程以後,再次啓動 Android Studio 對應的 adb 工具時, 該 adb 工具會發現當前沒有 adb 服務端,故而會自行啓動服務器進程,以下圖。因爲沒有鏈接設備,故而不會直接顯示出Shell。
經過命令行工具咱們能夠看到系統上如今存在了新的 adb 服務器進程,是由咱們剛纔使用 adb 工具的命令開啓的。
完成上述操做後,便可以將物理設備的USB調試模式打開,並鏈接至PC,再次使用 adb shell 命令,便可進入 adb 工具提供的Shell。
其餘
基於錯誤信息的描述,可能的解決方法還包括將兩個不一樣版本的 adb 工具更新成一致版本,這樣能夠避免每次使用時均要檢查是否已有不一樣版本的 adb 服務器進程存在。出現有兩個版本的 adb 工具的常見場景是系統可能同時安裝了兩個提供該工具的應用,如 Android Studio 和 Genymotion ,能夠參見 stackoverflow 的回答 。
根據 adb 工具運行的原理,若TCP端口 5037 被其餘進程佔用了,則也會出現報錯,典型的報錯信息是 "cannot bind to 127.0.0.1:5037 :t一般每一個套接字地址(協議/網絡地址/端口)只容許使用一次",此時可能須要考慮將佔用該端口的進程終止掉(在沒有反作用的狀況下)。