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 [-d|-e|-s <serialNumber>] <command>
コマンドを実行すると、プログラム内でadbクライアントが生成されます。クライアントは特定のエミュレータインスタンスと関連づくわけではないので、
複数のエミュレータ/デバイスを実行中である場合は-dオプションを渡してコマンドのターゲットとなるインスタンスを指定する必要があります。
このオプションの詳細は特定のエミュレータ/デバイスに対してコマンドを実行するを参照して下さい。
adbコマンドを実行する前に、adbサーバに接続されているエミュレータ/デバイスの一覧を把握しておくと良いでしょう。接続されているエミュレータ/デバイスの一覧はdevicesコマンドにより取得することが出来ます。
adb devices
各インスタンスについて以下のような結果が返されます。
<type>-<consolePort>となります。
例: emulator-5554offline — インスタンスがadbに接続されていないか、応答していないdevice — インスタンスはadbサーバに接続されている。ただし、このステータスが戻ってきてもAndroid
システムの起動が完了して利用可能な状態となっているとは限らない。通常はこのステータスが戻る。各インスタンスに関する出力は以下のようにフォーマットされます。
[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のサポートするコマンドとその機能、使用方法を一覧します。
| カテゴリ | コマンド | 機能説明 | コメント |
|---|---|---|---|
| オプション | -d |
adbコマンドをUSB接続されたデバイスのみに対して実行する | USBデバイスがひとつも接続されていない場合はエラーを返します。 |
-e |
adbコマンドをエミュレータに対してのみ実行する | エミュレータがひとつも実行されていない場合はエラーを返します。 | |
-s <serialNumber> |
adbコマンドをadbによって割り当てられたシリアルナンバー("emulator-5556"など)によって特定されるエミュレータ/デバイスに対してのみ実行します。 | 指定されていない場合はエラーを返します。 | |
| 一般 | devices |
接続されているエミュレータ/デバイスの一覧を表示します。 | エミュレータ/デバイスの一覧を取得するを参照して下さい。 |
help |
adbコマンドの一覧を表示します。 | ||
version |
adbのバージョンナンバーを表示します。 | ||
| Debug | logcat [<option>] [<filter-specs>] |
ログデータを画面に表示します。 | |
bugreport |
画面にバグ報告のためのdumpsys、dumpstate、logcat情報を表示します。 |
||
jdwp |
指定されたデバイス上で有効なJDWPプロセスの一覧を表示します。 | 以下のように、forward jdwp:<pid>コマンドを用いて特定のJDWPプロセスに接続することが出来ます。adb forward tcp:8000 jdwp:472jdb -attach localhost:8000
|
|
| データ | install <path-to-apk> |
.apkファイルへのフルパスを渡すことで、Androidアプリケーションをエミュレータ/デバイスにインストールすることが出来ます。 | |
pull <remote> <local> |
任意のファイルをエミュレータ/デバイスから開発マシンにコピーすることが出来ます。 | ||
push <local> <remote> |
任意のファイルを開発マシンからエミュレータ/デバイスにコピーすることが出来ます。 | ||
| ポートとネットワーク | forward <local> <remote> |
特定の自ホストポートをエミュレータ/デバイス上の特定ポートにフォワードすることが出来ます。 | ポートは以下のような方法で指定出来ます。
|
ppp <tty> [parm]... |
PPP over USBを実行出来ます。
なお、この場合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+Dかexitコマンドでシェルセッションを終了して下さい。
以下のセクションでは、シェルを使って出来ることをいくつか紹介します。
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リモートシェルに戻ることが出来ます。
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 |
エミュレータ/デバイスの実行を停止します。 |
Androidのログシステムはシステムデバッグ出力の収集機構を持っています。各アプリケーションやシステムの出力したログはサークルバッファに格納され、logcatコマンドによって閲覧/フィルタ出来ます。
以下のように、logcatコマンドによりシステムのログバッファ内容を閲覧/追跡することが出来ます。
[adb] logcat [<option>] ... [<filter-spec>] ...
以下のセクションではフィルタ指定の方法とコマンドオプションを解説します。Listing of logcat Command Optionsにオプションの概要が記載されているので参照して下さい。
logcatは開発マシンからもエミュレータ/デバイスに接続したadbリモートシェルからも実行出来ます。開発マシンからログ閲覧を行うには
$ adb logcat
を、adbリモートシェルからログ閲覧を行うには
# logcat
と、それぞれ実行します。
各Androidログメッセージにはタグと重要度が割り当てられています。
V — Verbose (重要度最低)D — DebugI — InfoW — WarningE — ErrorF — FatalS — Silent (重要度最高、というか表示されることは無いでしょう)システム上で使われているタグ-優先度ペアの一覧を見たい場合は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オプションを与えることで、これらのうち特定のメタデータフィールドのみを出力するようにメッセージの出力フォーマットを指定することが出来ます。
利用可能な表示フォーマットは以下の通りです。
brief — 重要度/タグと出力元プロセスのPIDを表示する(デフォルト)process — PIDのみを表示するtag — 重要度/タグのみを表示するthread — プロセス:スレッドと重要度/タグのみを表示するraw — メタデータ無しの、生ログを表示するtime — 出力日時、重要度/タグ、出力元プロセスのPIDを表示するlong — 全てのメタデータフィールドと各メッセージを空行付きで表示するlogcatを開始する際に、以下のように-vオプションを用いたログ出力フォーマットの指定が出来ます。
[adb] logcat [-v <format>]
threadフォーマットでの出力を得るためのコマンドは以下の通りです。
adb logcat -v thread
ただし、複数の-vオプションを指定することは出来ません。
Androidのロギングシステムは複数のサークルバッファを用いてメッセージを記録しますが、全てのログメッセージがデフォルトのサークルバッファに蓄積されるわけではありません。
その他のログメッセージはlogcatコマンドに-bオプションを付けることで閲覧出来ます。
このオプション指定により閲覧出来るバッファは以下の通りです。
radio — 電波/電話関連のメッセージを格納するバッファの内容を表示するevents — イベント関連のメッセージを格納するバッファの内容を表示するmain — メインログバッファの内容を表示する(デフォルト)-bオプションの使用方法:
[adb] logcat [-b <buffer>]
電波/電話関連のメッセージを格納したバッファを閲覧する場合の例:
adb logcat -b radio
デフォルト状態でAndroidシステムはstdoutとstderr(System.outとSystem.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にエントリを追加することで
この設定をエミュレータ/デバイスのデフォルトとすることも出来ます。
| オプション | 機能 |
|---|---|
-b <buffer> |
eventやradioといった、通常以外のログバッファを閲覧用に開きます。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サーバの停止にはkill-serverコマンドを利用します。その上で任意のadbコマンドを実行すると、サーバが再起動されます。