Android Debug Bridge

ADBの概要

  • エミュレータやデバイスの状態を管理する
  • デバイス上でシェルコマンドを実行する
  • エミュレータやデバイスのポートフォワードを管理する
  • エミュレータやデバイスとファイルのやりとりを行う

本ドキュメントで扱うトピック

  1. adbコマンドを実行する
  2. エミュレータ/デバイスの一覧を取得する
  3. 特定のエミュレータ/デバイスに対してコマンドを実行する
  4. アプリケーションをインストールする
  5. ポートフォワーディングを行う
  6. エミュレータ/デバイスとファイルのやり取りを行う
  7. adbコマンドの一覧
  8. シェルコマンドを実行する
  9. logcatでのロギングを有効化する
  10. adbサーバを停止する

参照

  1. Emulator

Android Debug Bridge (adb)は、エミュレータやAndroidベースのデバイスを管理するための多彩な機能を持った、以下の3コンポーネントから成るクライアント-サーバ型のプログラムです。

adbクライアントは、起動されるとまずadbサーバの稼動状態を確認し、稼動していなければサーバプロセスを起動します。起動されたサーバは ローカルのTCP 5037番ポートにてadbクライアントからのコマンド待ち状態となります。全てのadbクライアントはadbサーバとの通信に5037番ポートを使うこととなります。

次にサーバは5555番ポートから5585番ポートまでの奇数番のポートをスキャンし、実行中のエミュレータ/デバイスとの接続を確立します。サーバが adbデーモンを発見すると、そのポートとの接続を確立します。なお、各エミュレータ/デバイスは連続した2つのポートを、偶数番=コンソール接続用、奇数番=adb接続用と、以下の例のように使用します。

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

上記のように、adbに5555番ポートで接続されたエミュレータインスタンスは、コンソール接続を5554番ポートでlistenすることになります。

サーバでの全エミュレータインスタンスとの接続が完了すると、adbコマンドを用いて各インスタンスへのアクセスを行うことが出来るようになります。 サーバ側でエミュレータ/デバイスへの接続管理や複数のadbクライアントからのコマンドを処理するため、任意のクライアントやスクリプトから任意のインスタンスを制御することが出来ます。

以下ではadbの機能にアクセスしたり、エミュレータ/デバイスの状態を管理するためのコマンドについて解説します。なお、ADTプラグインをインストールしたeclipse環境で Androidアプリケーションの開発を行っている場合は、コマンドラインからadbにアクセス必要はなく、adbはADTプラグインによってeclipse IDEに対して透過的に統合されています。 しかし、デバッグ上の都合など、必要な際にはadbを直接呼び出すことが出来ます。

adbコマンドを実行する

以下のようにして開発用のマシンからコマンドラインで直接実行、あるいはスクリプト内から呼び出すことが出来ます。

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

コマンドを実行すると、プログラム内でadbクライアントが生成されます。クライアントは特定のエミュレータインスタンスと関連づくわけではないので、 複数のエミュレータ/デバイスを実行中である場合は-dオプションを渡してコマンドのターゲットとなるインスタンスを指定する必要があります。 このオプションの詳細は特定のエミュレータ/デバイスに対してコマンドを実行するを参照して下さい。

実行中のエミュレータ/デバイス一覧を取得する

adbコマンドを実行する前に、adbサーバに接続されているエミュレータ/デバイスの一覧を把握しておくと良いでしょう。接続されているエミュレータ/デバイスの一覧はdevicesコマンドにより取得することが出来ます。

adb devices

各インスタンスについて以下のような結果が返されます。

各インスタンスに関する出力は以下のようにフォーマットされます。

[serialNumber] [state]

まとめると、devicesコマンドの出力例は以下のようになります。

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

エミュレータ/デバイスが実行されていない場合、no deviceとの応答が戻ります。

特定のエミュレータ/デバイスに対してコマンドを実行する

複数のエミュレータ/デバイスが実行されている場合、adbコマンドの実行対象インスタンスを指定する必要があります。このために用意されているのが-sオプションで、以下のように使用します。

adb -s <serialNumber> <command> 

見ての通り、adbによって生成されたシリアルナンバーを用いてアクセスします。実行中のエミュレータ/デバイスのシリアルナンバー一覧はdevicesコマンドを使うことで取得して下さい。

例:

adb -s emulator-5556 install helloWorld.apk

なお、-sオプションによる対象エミュレータ/デバイスの指定を行わなかった場合、adbはエラーを返します。

アプリケーションをインストールする

adbのinstallコマンドを使うと、開発マシンからエミュレータ/デバイスに対するアプリケーションのコピーを行うことが出来ます。 この場合、コマンドに対してインストール対象の.apkファイルを指定する必要があります。

adb install <path_to_apk>

エミュレータ/デバイスにインストールすることの出来る.apkファイルの作成方法については、Android Asset Packaging Tool(aapt)を参照して下さい。

ADTプラグインをインストールしたeclipse環境においては、ADTの機能を使うことでadbやaaptを直接使うことなくエミュレータ/デバイスへのアプリケーションインストールを行うことが出来ます。

ポートフォワーディングを行う

forwardコマンドでは、ポートフォワーディングの設定を行うことが出来ます。 — 特定の自ホストポートに対するリクエストをエミュレータ/デバイス上の指定ポートに対して 転送することが出来ます。自ホストの6100番ポートをエミュレータ/デバイスの7100番ポートに転送する場合は以下のようにします。

adb forward tcp:6100 tcp:7100

また、adbでは以下のようにUNIXドメインソケットの名前を指定して転送を行うことも出来ます。

adb forward tcp:6100 local:logd 

エミュレータ/デバイスとファイルのやり取りを行う

adbのpullコマンドとpushコマンドを使うことで、エミュレータ/デバイスとのファイル受け渡しが可能です。install コマンドは.apkファイルを特定の場所にコピーするだけですが、pullコマンドやpushコマンドではエミュレータ/デバイス上の任意の場所に ディレクトリやファイルをコピーすることが出来ます。

ファイルやディレクトリ(再帰的に)をエミュレータやデバイスからコピーする場合は、

adb pull <remote> <local>

とします。ファイルやディレクトリ(再帰的に)をエミュレータやデバイスコピーする場合は

adb push <local> <remote>

とします。上記において<local><remote>はそれぞれターゲットとなるファイル/ディレクトリの 開発マシン(local)での位置とエミュレータ/デバイス(remote)での位置を指します。

例:

adb push foo.txt /sdcard/foo.txt

adbコマンドの一覧

以下の表に、adbのサポートするコマンドとその機能、使用方法を一覧します。

カテゴリ コマンド 機能説明 コメント
オプション -d adbコマンドをUSB接続されたデバイスのみに対して実行する USBデバイスがひとつも接続されていない場合はエラーを返します。
-e adbコマンドをエミュレータに対してのみ実行する エミュレータがひとつも実行されていない場合はエラーを返します。
-s <serialNumber> adbコマンドをadbによって割り当てられたシリアルナンバー("emulator-5556"など)によって特定されるエミュレータ/デバイスに対してのみ実行します。 指定されていない場合はエラーを返します。
一般 devices 接続されているエミュレータ/デバイスの一覧を表示します。 エミュレータ/デバイスの一覧を取得するを参照して下さい。
help adbコマンドの一覧を表示します。  
version adbのバージョンナンバーを表示します。  
Debug logcat [<option>] [<filter-specs>] ログデータを画面に表示します。  
bugreport 画面にバグ報告のためのdumpsysdumpstatelogcat情報を表示します。  
jdwp 指定されたデバイス上で有効なJDWPプロセスの一覧を表示します。 以下のように、forward jdwp:<pid>コマンドを用いて特定のJDWPプロセスに接続することが出来ます。
adb forward tcp:8000 jdwp:472
jdb -attach localhost:8000
データ install <path-to-apk> .apkファイルへのフルパスを渡すことで、Androidアプリケーションをエミュレータ/デバイスにインストールすることが出来ます。  
pull <remote> <local> 任意のファイルをエミュレータ/デバイスから開発マシンにコピーすることが出来ます。  
push <local> <remote> 任意のファイルを開発マシンからエミュレータ/デバイスにコピーすることが出来ます。  
ポートとネットワーク forward <local> <remote> 特定の自ホストポートをエミュレータ/デバイス上の特定ポートにフォワードすることが出来ます。 ポートは以下のような方法で指定出来ます。
  • tcp:<ポート番号>
  • local:<UNIXドメインソケット名>
  • dev:<キャラクタデバイス名>
  • jdwp:<pid>
ppp <tty> [parm]... PPP over USBを実行出来ます。
  • <tty> — PPPストリーム用のtty。例: dev:/dev/omap_csmi_ttyl
  • [parm]... — 任意で付加するPPP/PPPDオプション。例: defaultroutelocalnotty

なお、この場合PDP接続を自動的に開始してはならないことに留意して下さい。

スクリプト処理 get-serialno adbのシリアル番号文字列を表示します。 エミュレータ/デバイスの一覧を取得するを参照して下さい。
get-state エミュレータ/デバイスのadb状態を返します。
wait-for-device デバイスが接続される(状態がdeviceとなる)まで処理を続けます。 このコマンドを以下のようにして他のadbコマンドより前に実行することで、エミュレータ/デバイスの接続後に他のコマンドを実行するような制御が可能です。
adb wait-for-device shell getprop
前述のようにこのコマンドはシステムの起動完了を待つためのものではありません。そのため、システムが完全に起動した状態で実行する必要のあるコマンドの前置きとして使うことは出来ません。 例えばinstallコマンドはシステムが完全に起動した後でしかアクセス出来ないAndroidパッケージマネージャに依存しています。そのため
adb wait-for-device install <app>.apk
と指定するとinstallコマンドが、adbとエミュレータ/デバイスの接続が確立された時点(システムの完全起動前)で実行されてしまうためエラーとなります。
サーバ start-server adbサーバプロセスが起動しているかチェックし、起動していない場合は起動します。  
kill-server adbサーバプロセスを停止します。  
シェル shell 対象エミュレータ/デバイスのリモートシェルを起動します。 シェルコマンドを実行するを参照して下さい。
shell [<shellCommand>] 対象エミュレータ/デバイス上でシェルコマンドを実行した上でリモートシェルを終了します。

シェルコマンドを実行する

adbにはエミュレータやデバイス上で様々なコマンドを実行するためのashシェルが含まれています。 コマンドバイナリはエミュレータやデバイス上の以下の場所に格納されています。

/system/bin/...

adbリモートシェルのエミュレータ/デバイスへの接続/未接続に関わらず、shellコマンドを用いるとシェルコマンドを実行することが出来ます。

リモートシェルを使わずにshellコマンドにより単一コマンドを実行するための方法は以下の通りです。

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

エミュレータ/デバイスのリモートシェルにアクセスするためには、shellコマンドを以下のように使います。

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

リモートシェルでの作業が完了したらCTRL+Dexitコマンドでシェルセッションを終了して下さい。

以下のセクションでは、シェルを使って出来ることをいくつか紹介します。

シェル経由でsqlite3のデータベースにアクセスする

adbリモートシェルからsqlite3コマンドラインプログラムを使ってAndroidアプリケーションによって 作成されたSQLiteデータベース管理することが出来ます。sqlite3ツールにはテーブル内容を表示する.dumpコマンドや 既存テーブルのCREATEステートメントを表示する.schemaコマンドなど、多くの有用なコマンドが含まれています。 また、このコマンドを使うとSQLiteコマンドを直接実行することも出来ます。

sqlite3は、前述の方法によってエミュレータのリモートシェルに接続した上で、sqlite3コマンドを実行することで利用出来ます。 sqlite3コマンドの実行時に、処理対象のデータベースファイルをフルパスで指定することも可能です。 エミュレータ/デバイスはSQLite3データベースを/data/data/<package_name>/databases/に格納しています。

例:

$ adb -s emulator-5554 shell
# sqlite3 /data/data/com.example.google.rss.rssexample/databases/rssitems.db
SQLite version 3.3.12
Enter ".help" for instructions
.... enter commands, then quit...
sqlite> .exit 

sqlite3の実行中は、シェル内でsqlite3コマンドを実行出来ます。exitコマンドかCTRL+Dにより、adbリモートシェルに戻ることが出来ます。

UI/Application Exerciser Monkey

Monkeyは、エミュレータやデバイス上でクリック、タッチ、ジェスチャーに代表されるユーザイベントやその他システムレベルの イベントを擬似的に発生させるものです。Monkeyを利用することで開発中のアプリケーションの負荷テストを行うことが出来ます。 (訳注:同じシードを与えることで)再現可能なランダム挙動をさせることも出来ます。

最も簡単な使い方は以下のようなもので、この場合500個の擬似的なイベントが発生します。

$ adb shell monkey -v -p your.package.name 500

MonkeyのコマンドラインオプションについてはUI/Application Exerciser Monkeyページを参照して下さい。

その他のシェルコマンド

以下に、利用可能なadbシェルコマンドをいくつか紹介します。全コマンドはエミュレータを実行し、adb -helpコマンドを実行することで確認出来ます。

adb shell ls /system/bin

ほとんどのコマンドについてヘルプが書かれています。

シェルコマンド 機能 コメント
dumpsys システムデータを画面にダンプします。 Dalvik Debug Monitor Service (DDMS) ツールには、もっと使いやすい統合デバッグ環境が含まれています。
dumpstate ステート情報をファイルにダンプします。
logcat [<option>]... [<filter-spec>]... 電波ログを有効にし、画面に表示します。
dmesg カーネルデバッグメッセージを画面に表示します。
start エミュレータ/デバイスを起動(または再起動)します。  
stop エミュレータ/デバイスの実行を停止します。  

logcatでのロギングを有効化する

Androidのログシステムはシステムデバッグ出力の収集機構を持っています。各アプリケーションやシステムの出力したログはサークルバッファに格納され、logcatコマンドによって閲覧/フィルタ出来ます。

logcatコマンドの使い方

以下のように、logcatコマンドによりシステムのログバッファ内容を閲覧/追跡することが出来ます。

[adb] logcat [<option>] ... [<filter-spec>] ...

以下のセクションではフィルタ指定の方法とコマンドオプションを解説します。Listing of logcat Command Optionsにオプションの概要が記載されているので参照して下さい。

logcatは開発マシンからもエミュレータ/デバイスに接続したadbリモートシェルからも実行出来ます。開発マシンからログ閲覧を行うには

$ adb logcat

を、adbリモートシェルからログ閲覧を行うには

# logcat

と、それぞれ実行します。

ログ出力をフィルタする

各Androidログメッセージにはタグ重要度が割り当てられています。

システム上で使われているタグ-優先度ペアの一覧を見たい場合はlogcatを実行し<priority>/<tag>で表される最初の2カラムを確認して下さい。

メッセージが重要度"I"で"ActivityManager"タグの付けられたログの出力例を示します。

I/ActivityManager(  585): Starting activity: Intent { action=android.intent.action...}

ログ出力量を管理出来るレベルまで減らすために、ログ出力に対してフィルタをかけることが出来ます。フィルタ指定はタグと重要度情報の組み合わせにてかけることが出来、 こうすることで指定タグのついた他のメッセージ(訳注:重要度の一致しないもの)の除外出力が可能です。

フィルタはtag:priority ...というフォーマットで指定します。ここでtagは出力したいタグを、priorityは 出力したい最低レベルを指定します。指定タグにマッチしたメッセージのうち、指定レベル以上のログのみが出力されます。 フィルタ組(tag:priority)は好きなだけホワイトスペースで区切って渡すことが出来ます。

"ActivityManager"タグが付けられた"Info"レベル以上のログと、"MyApp"タグが付けられた"Debug"レベル以上のログのみを出力する例:

adb logcat ActivityManager:I MyApp:D *:S

上記指定のうち最後の要素(*:S)で全タグの出力レベルを"silent"に指定し、"View"と"MyApp"のログのみが出力されるようにしています。 *:Sは、指定したログのみを出力する、"ホワイトリスト指定"のための便利な機能です。

以下のフィルタ指定では全タグの"warning"レベル以上の全ログを表示します。

adb logcat *:W

logcatを開発マシン上で(つまり、adbリモートシェル上ではなく)実行している場合、ANDROID_LOG_TAGS環境変数の設定によってデフォルトのフィルタ指定をかけることが出来ます。

export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"

逆に、ANDROID_LOG_TAGSフィルタはエミュレータ/デバイスに対してエクスポートされないため、logcatを リモートシェルで実行している場合やadb shell logcatを実行している場合には無効となります。

ログ出力フォーマットを指定する

ログメッセージにはタグや重要度以外にもいくつかのメタデータフィールドが含まれます。-vオプションを与えることで、これらのうち特定のメタデータフィールドのみを出力するようにメッセージの出力フォーマットを指定することが出来ます。 利用可能な表示フォーマットは以下の通りです。

logcatを開始する際に、以下のように-vオプションを用いたログ出力フォーマットの指定が出来ます。

[adb] logcat [-v <format>]

threadフォーマットでの出力を得るためのコマンドは以下の通りです。

adb logcat -v thread

ただし、複数の-vオプションを指定することは出来ません。

その他のログバッファを閲覧する

Androidのロギングシステムは複数のサークルバッファを用いてメッセージを記録しますが、全てのログメッセージがデフォルトのサークルバッファに蓄積されるわけではありません。 その他のログメッセージはlogcatコマンドに-bオプションを付けることで閲覧出来ます。 このオプション指定により閲覧出来るバッファは以下の通りです。

-bオプションの使用方法:

[adb] logcat [-b <buffer>]

電波/電話関連のメッセージを格納したバッファを閲覧する場合の例:

adb logcat -b radio

標準出力・標準エラー出力を閲覧する

デフォルト状態でAndroidシステムはstdoutstderr(System.outSystem.err)への出力を /dev/nullへ捨てています。Dalvik VMを実行している場合、出力のコピーをログファイルに記録するよう設定することが出来ます。 この場合、システムはメッセージに対してstdoutタグまたはstderrタグを付け、重要度Iで書き出します。

この方法で出力を行うためには以下のようにエミュレータ/デバイスを停止し、その後setpropシェルコマンドを実行して出力のリダイレクト設定を行う必要があります。

$ adb shell stop
$ adb shell setprop log.redirect-stdio true
$ adb shell start

ここで行った設定は、エミュレータ/デバイスを停止するまで有効となりますが、デバイス上の/data/local.propにエントリを追加することで この設定をエミュレータ/デバイスのデフォルトとすることも出来ます。

logcatコマンドのオプション一覧

オプション 機能
-b <buffer> eventradioといった、通常以外のログバッファを閲覧用に開きます。mainバッファがデフォルトです。その他のログバッファを閲覧するを参照して下さい。
-c ログを全てクリア(フラッシュ)して終了します。
-d ログを画面にダンプして終了します。
-f <filename> ログ出力を指定したファイルに書き出します。デフォルトはstdout(標準出力)です。
-g 指定したログバッファのサイズを表示して終了します。
-n <count> ローテートして保存されるログの数を設定します。デフォルトは4です。このオプションを指定する際には-rオプションも指定する必要があります。
-r <kbytes> 指定キロバイトの出力ごとにログファイルをローテートさせます。デフォルト値は16です。このオプションを指定する際には-fオプションも指定する必要があります。
-s デフォルトのフィルタレベルをsilentに指定します。
-v <format> ログメッセージの出力フォーマットを設定します。デフォルトはbriefです。指定可能なフォーマットの一覧はControlling Log Output Formatを参照して下さい。

adbサーバを停止する

場合によってはadbサーバプロセスを停止して再起動する必要があるかもしれません。例えば、adbがコマンドに応答しない場合、サーバを停止して再起動することで回復する可能性があります。

adbサーバの停止にはkill-serverコマンドを利用します。その上で任意のadbコマンドを実行すると、サーバが再起動されます。