天天看點

Android* 作業系統上的應用程式遠端調試 Android* 作業系統上的應用程式遠端調試

- 20:00 送出

Android* 作業系統應用程式遠端調試

Android* Debug Bridge

Android Debug Bridge (ADB) 是一種指令行工具,可處理主機上的調試程式(通常為 GDB* 或 DDMS*(Dalvik* 調試監測程式伺服器)以及 ADT)和目标上運作的 Android* 映像之間的調試通信。 目标映像可運作在模拟裝置上或實體開發裝置(通過 USB-OTG (On-The-Go) 或 USB 轉以太網擴充卡與其通信)上。 簡而言之,ADB 是一座橋梁,讓調試 Android* 上的應用程式成為可能。

您所連接配接或模拟的裝置涉及大量形狀因素。 通常裝置可能是智能手機或平闆電腦。 也可以是醫療用平闆電腦或工業、家庭能源管理、倉儲領域或任意數量智能系統應用程式的嵌入式裝置。

設定 Android Debug Bridge 可讓基于英特爾® 淩動TM處理器的平台的遠端調試與其他架構上的調試不會有太大差别。

設定 ADB*

如果目标映像運作在實體裝置上,則首先需要支援 USB-OTG 或 USB 轉以太網。 要支援 USB 轉以太網,需要重新建構核心配置。 如果需要,您的原始裝置制造商将為您提供必要資訊。

在此概述一下主要步驟

1.      在 Android Manifest 中将您的應用程式聲明為“可調試”。

在使用 Eclipse 時,可跳過該步驟,因為直接從 Eclipse IDE 運作應用程式時會自動啟用調試。

在 <code>AndroidManifest.xml </code>檔案中将 <code>android:debuggable="true" </code>添加至<code> &lt;application&gt; </code>元素。

注:如果在清單檔案中手動啟用調試,在進行建構以釋出之前務必先禁用它(您釋出的應用程式通常應該不可調試)。

2.      打開裝置上的“USB 調試”。

在裝置上,轉至“設定 &gt; 應用程式 &gt; 開發”并啟用“USB 調試”(在 Android 4.0 裝置上,設定路徑為“設定 &gt; 開發人員選項”)。

3.      設定系統以檢測裝置。

o   如果在 Mac OS* X 上開發,則無需操作。 可直接跳過該步驟。

o   如果在 Ubuntu* Linux* 上開發,則需要添加一個 <code>udev</code> 規則檔案,該檔案包含要用于開發的每種裝置的 USB 配置。 在規則檔案中,通過唯一的供應商 ID 表示每個裝置制造商,該 ID 通過 <code>ATTR{idVendor}</code> 屬性指定。

以超級使用者身份登入并建立該檔案: <code>/etc/udev/rules.d/51-android.rules</code>。

按照下列格式将廠商添加至檔案:

<code>SUBSYSTEM=="usb", ATTR{idVendor}=="&lt;vendor id&gt;", MODE="0666", GROUP="plugdev"</code>

現在執行:

<code>chmod a+r /etc/udev/rules.d/51-android.rules</code>

在通過 USB 插入時,可通過從 <code>SDK platform-tools/ </code>目錄執行 <code>adb devices</code> 驗證裝置是否已連接配接。 如果已連接配接,将看到裝置名稱作為“裝置”列出。

對于 CDK 上引導的 Android 作業系統,将一根 USB-OTG 電纜連接配接至 CDK 上的(USB 微型 b)端口,将電纜的另一端 (USB A) 連接配接至開發主機。

如果一切都正常,就能夠運作以下指令看到已連接配接裝置:

<code>$ adb devices</code>

<code>* daemon not running. starting it now *</code>

<code>* daemon started successfully *</code>

<code>List of devices attached</code>

<code>0123456789ABCDEF  device</code>                                                       

注: 要了解将哪個裝置名配置設定給了 Linux 開發主機上的該連接配接,可檢視 dmesg 查找“usb-storage: device found at &lt;num&gt;”的位址然後進行“ls -l /dev/bus/usb/*”清單來查找該數字。

Windows 上的 ADB*

或 installer_r18-windows.exe)。

在安裝 Android* SDK 後,adb.exe 将位于 &lt;install-dir&gt;\android-sdk\platform-tools

ADB 主機-用戶端通信

至此我們關注的是在開發主機上安裝 ADB。 在現實中,它是用戶端-伺服器程式,具有三個元件:

一個用戶端,運作于開發主機上。 可通過執行 adb 指令從 shell 調用用戶端。 其他諸如 ADT 插件和 DDMS 的 Android 工具也能建立 adb 用戶端。

一個伺服器,作為背景程序運作于開發主機上。 伺服器管理用戶端和運作于模拟器或裝置上的 adb 守護程式之間的通信。

一個守護程式,作為背景程序運作于每個模拟器或裝置執行個體上。

在啟動 adb 用戶端時,用戶端會先檢查是否已經有 adb 伺服器程序正在運作。 如果沒有,則會啟動伺服器程序。 當伺服器啟動時,它會綁定至本地 TCP 端口 5037 并監聽從 adb 用戶端發出的指令,所有 adb 用戶端都使用端口 5037 與 adb 伺服器通信。

然後伺服器會建立與所有正在運作的模拟器/裝置執行個體的連接配接。 它會通過在範圍 5555 至 5585(模拟器/裝置使用的範圍)中掃描奇數編号的端口找到模拟器/裝置執行個體。 在找到 adb 守護程式處,建立與該端口之間的連接配接。 請注意,每個模拟器/裝置執行個體擷取一對序列端口 - 一個偶數編号的端口用于控制台連接配接,一個奇數編号的端口用于 adb 連接配接。 例如:

<code> Emulator 1, console: 5554</code>

<code> Emulator 1, adb: 5555</code>

<code> Emulator 2, console: 5556</code>

<code> Emulator 2, adb: 5557 ...</code>

如示例所示,在端口 5555 上連接配接至 adb 的模拟器執行個體與控制台監聽端口 5554 的執行個體相同。

一旦伺服器建立與所有模拟器執行個體之間的連接配接,就可使用 adb 指令來控制和通路那些執行個體。 由于伺服器會管理指向模拟器/裝置執行個體的連接配接并處理來自多個 adb 用戶端的指令,您可通過任何用戶端(或腳本)控制任何模拟器/裝置執行個體。

啟動 ADB 

鍵入 "adb shell"。 将得到一個 # 号來訓示連接配接成功。

<code>$ adb shell</code>

主要 ADB 裝置指令 

下面所列的指令可幫助将接受調試的應用程式從指令行轉移至目标裝置或模拟裝置。 這點非常有用,尤其是在沒有 ssh 終端連接配接可用時。

<code>  adb push &lt;local&gt; &lt;remote&gt;    - copy file/dir to device</code>

<code>  adb pull &lt;remote&gt; [&lt;local&gt;]  - copy file/dir from device</code>

<code>  adb sync [ &lt;directory&gt; ]     - copy host-&gt;device only if changed</code>

<code>                                 (-l means list but don't copy)</code>

<code>                                 (see 'adb help all')</code>

<code>  adb shell                    - run remote shell interactively</code>

<code>  adb shell &lt;command&gt;          - run remote shell command&lt;</code>

<code>  adb emu &lt;command&gt;            - run emulator console command&lt;</code>

<code>  adb logcat [ &lt;filter-spec&gt; ] - View device log</code>

<code>  adb forward &lt;local&gt; &lt;remote&gt; - forward socket connections </code><code>forward specs are one of:&lt;</code><code>tcp:&lt;port&gt;&gt;</code>

<code>                                  localabstract:&lt;unix domain socket </code><code>name&gt;</code>

<code>                                  localreserved:&lt;unix domain socket </code><code>name&gt;</code>

<code>                                  localfilesystem:&lt;unix domain socket name&gt;</code>

<code>                                   dev:&lt;character device name&gt;</code>

<code>                                   jdwp:&lt;process pid&gt; (remote only)</code>

<code>  adb jdwp                     - list PIDs of processes hosting a JDWP </code><code>transport</code>

<code>  adb install [-l] [-r] [-s] &lt;file&gt; - push this package file to the </code><code>device and install it</code>

<code>                                 ('-l' means forward-lock the app)</code>

<code>                                 ('-r' means reinstall the app, keeping </code><code>its data)</code>

<code>                                 ('-s' means install on SD card instead </code><code>of internal storage)</code>

<code>  adb uninstall [-k] &lt;package&gt; - remove this app package from device</code>

<code>                                 ('-k' means keep the data and cache </code><code>directories)</code>

在使用 GDB 進行調試時,運作于裝置上的 gdbserver 用于處理調試通信,但您仍可将基本 USB 轉以太網擴充卡用于 ADB 以處理通信傳輸層,在該層上 gdbserver 借助 tcp/ip 協定并在 GDB 運作于開發主機上的情況下進行通信。

有一個 gdbclient 應用程式,其可設定調試通信環境并在進行程式調試的裝置上啟動 gdbserver。

<code>usage: gdbclient EXECUTABLE :PORT [PROG_PATH]</code>

<code>EXECUTABLE  executable name (default app_process)</code>

<code>PORT  commection port (default :1234)</code>

<code>PROG_PATH   executable full path on target (ex /system/bin/mediaserver)</code>

如果設定了 PROG_PATH,gdclient 會嘗試啟動 gdbserver 并将其附加至運作的 PROG_PATH

要明确啟動 gdbserver,可使用以下指令

<code># gdbserver :1234 --attach 269</code>

<code>Attached; pid = 269</code>

<code>Listening on port 1234</code>

下面的逐漸調試會話啟動指令展示了 ADB 如何在将 GDB 而非 ADT 或 DDMS 用于調試的情況下仍然作為調試通信的基礎。 讓我們假定使用的是端口 1234。

啟動程序:

<code>gdbserver :1234 /system/bin/executable</code>

或附加至現有程序:

<code>gdbserver :1234 --attach pid</code>

在您的工作站上,使用 adb 将端口 1234 轉發至裝置:

<code>adb forward tcp:1234 tcp:1234</code>

啟動位于源代碼樹 "prebuilt" 區域中的特殊版本 gdb:

<code>prebuilt/Linux/toolchain-eabi-4.x.x/bin/i686-android-linux-gdb (for Linux)</code>

<code>prebuilt/darwin-x86/toolchain-eabi-4.x.x/bin/i686-android-linux-gdb (for Darwin)</code>

如果兩個特殊版本的 gdb 都無法找到,運作 find prebuilt -name i686-android-linux-gdbin your source tree 來查找并運作最新版本。

務必使用符号目錄中而非主要 android 目錄中可執行檔案的副本,因為主要目錄中的副本已去除了符号資訊。

在 GDB 中,告知 GDB 何處查找将要加載的共享庫:

<code>set solib-absolute-prefix /absolute-source-path/out/target/product/product-name/symbols</code>

<code>set solib-search-path /absolute-source-path/out/target/product/product-name/symbols/system/lib</code>

absolute-source-path 為您的源代碼樹的路徑。

確定指定正确的目錄 – 如果您弄錯目錄 GDB 可能不會告知您。

通過發出 GDB 指令連接配接至裝置:

<code>(gdb) target remote :1234</code>

:1234 告知 gdb 連接配接至本地主機端口 1234,後者通過 adb 橋接至裝置。

現在可以用和之前相同的方式使用 GDB 開始調試運作于 Android* 上的 C/C++ 代碼。

使用 Eclipse* 的 ADT* 插件來調試 Android* 應用程式

對于基于英特爾® 架構的模拟器以及目标裝置,ADT* 插件可提供完整的內建 Eclipse* IDE 的應用程式調試。 它使用不同的功能集提供兩種不同的調試視圖。

您可根據需要選用其中一個,在調試應用程式時二者都可提供不同的強度。

Eclipse 中的調試視圖*  

Eclipse 中調試視圖可讓您通路以下頁籤:

調試 – 顯示之前和目前調試的 Android 應用程式及其目前運作的線程

變量 – 在設定了斷點時,顯示代碼執行期間的變量值

斷點 – 顯示您的應用程式代碼中設定的斷點清單

LogCat – 可讓您實時檢視系統日志資訊。 LogCat 頁籤也可在 DDMS 視圖中使用。

通過單擊 Window(視窗)&gt; Open Perspective(打開視圖)&gt; Debug(調試)可通路調試視圖。 有關 Eclipse 調試程式的詳細資訊,請參閱相應文檔。

DDMS 視圖

Eclipse 中的 DDMS 視圖可讓您在 Eclipse IDE 中通路 DDMS 的所有功能。 您可使用 DDMS 的以下部分:

裝置 – 顯示連接配接至 ADB 的裝置和 AVD 清單。

模拟器控制 – 讓您執行裝置功能。

LogCat – 讓您實時檢視系統日志資訊。

線程 – 顯示虛拟機中目前運作的線程。

堆區 – 顯示虛拟機的堆區使用。

配置設定跟蹤器 – 顯示對象的記憶體配置設定。

檔案管理器 – 可讓您探索裝置的檔案系統。

用于調試的應用程式運作時環境

調試為基于英特爾® 架構的裝置設計的 Android* 應用程式的不同之處在于何時設定調試目标裝置。

使用屬于 Android* SDK 一部分的 Android* 虛拟裝置管理器選擇目标裝置,轉到 Eclipse* IDE 下拉菜單中的 Window(視窗)&gt; AVD Manager(AVD 管理器)。 在此您需要確定選擇英特爾淩動作為作業系統鏡像和裝置模拟的 EABI 目标。

如果遵照本文開始概述的有關設定 ADB* 和建立指向實體裝置的調試橋的步驟,就會看到 Eclipse IDE 中的裝置選擇器界面,從中可選擇用于應用程式開發和調試的目标。

除此之外,為基于英特爾® 架構的裝置設計的 Android* 應用程式和為 ARM* 架構設計的 Android* 應用程式在調試上确實存在着差别。

分類: 

繼續閱讀