Android Studio では、以下のようなことができるデバッガーを提供しています:
- アプリをデバッグするデバイスを選択します。
- Java, Kotlin, および C/C++ コードにブレークポイントを設定する。
- Examine variables and evaluate expressions at runtime.
このページには、デバッガーの基本操作に関する指示が記載されています。 より詳細なドキュメントについては、IntelliJ IDEA デバッグのドキュメントも参照してください。
Enable debugging
デバッグを開始する前に、次のように準備する必要があります:
- Enable debugging on your device:
emulator を使用している場合、これはデフォルトで有効になっています。 しかし、接続されたデバイスでは、デバイス開発者オプションでデバッグを有効にする必要があります。
- Run a debuggable build variant:
ビルド構成に
debuggable true
が含まれるビルドバリアを使用する必要があります。 通常、すべての Android Studio プロジェクトに含まれているデフォルトの「デバッグ」バリアントを選択できます (build.gradle
ファイルには表示されませんが)。 しかし、デバッグ可能な新しいビルド タイプを定義する場合、ビルド タイプに `debuggable true` を追加する必要があります:android { buildTypes { customDebugType { debuggable true ... } }}
このプロパティは、C/C++ コードのあるモジュールにも適用されます。 (
jniDebuggable
プロパティはもはや使用されません。)アプリがデバッグしたいライブラリ モジュールに依存している場合、そのライブラリも
debuggable true
でパッケージ化し、そのデバッグ シンボルを保持する必要があります。
Start debugging
デバッグ セッションは次のように開始できます。
- アプリ コードにブレークポイントを設定します。
- ツールバーで、ターゲット デバイス ドロップダウン メニューからアプリをデバッグするデバイスを選択します。
デバイスが設定されていない場合、USB でデバイスを接続するか、Android Emulator を使用する AVD を作成する必要があります。
- ツールバーで、[デバッグ ] をクリックします。
「実行からデバッグに切り替えるかどうか」を尋ねるダイアログが表示されたら、それはアプリがすでにデバイス上で実行されていて、デバッグを開始するために再起動することを意味します。 アプリの同じインスタンスを実行し続けたい場合は、[Cancel Debug] をクリックし、代わりに実行中のアプリにデバッガーをアタッチします。
そうしないと、Android Studio は APK を構築し、デバッグ キーで署名して、選択したデバイスにインストールし、それを実行します。 プロジェクトにCおよびC++コードを追加する場合、Android StudioはDebugウィンドウでLLDBデバッガを実行してネイティブコードをデバッグすることもできます。
- デバッグウィンドウが開いていない場合は、図1に示すように、[表示]>[ツールウィンドウ]>[デバッグ](またはツールウィンドウバーで[デバッグ]をクリック)を選択し、[デバッガ]タブをクリックします。
図1. デバッガー] ウィンドウ。現在のスレッドと変数のオブジェクト ツリーを表示
実行中のアプリにデバッガーを取り付ける
すでにデバイスでアプリを実行している場合、次のようにすれば、アプリを再起動せずにデバッグを開始することができます。
- Click Attach debugger to Android process をクリックします。
- [プロセスの選択]ダイアログで、デバッガをアタッチするプロセスを選択します。
エミュレータやルート化されたデバイスを使用している場合、[すべてのプロセスを表示]をチェックすると、すべてのプロセスを表示することができます。
[Use Android Debugger Settings from] ドロップダウン メニューから、既存の実行/デバッグの設定を選択できます。 (C および C++ コードの場合、これにより LLDB 起動コマンド、LLDB ポストアタッチコマンド、およびシンボルディレクトリを既存の構成で再利用することができます)。 既存のラン/デバッグ構成がない場合は、Create New を選択します。 この選択により、Debug Type ドロップダウン・メニューが有効になり、別のデバッグ・タイプを選択することができます。 デフォルトでは、Android StudioはAutoデバッグタイプを使用して、プロジェクトにJavaまたはC/C++コードのいずれが含まれているかに基づいて、最適なデバッガーオプションを選択します。
- [OK]をクリックします。
[Debug]ウィンドウが表示されます。
Note: Android Studioのデバッガとガベージコレクタは緩やかに統合されています。 Android 仮想マシンは、デバッガーが認識しているオブジェクトは、デバッガーが切断されるまでガベージコレクションされないことを保証しています。 このため、デバッガーが接続されている間、時間の経過とともにオブジェクトが蓄積されることがあります。 たとえば、デバッガーが実行中のスレッドを認識した場合、関連する Thread
オブジェクトは、スレッドが終了していても、デバッガーが切断するまでガベージ コレクションされません。
Change the debugger type
Android Studio では、Java/Kotlin コードと C/C++ コードのデバッグに異なるデバッグ ツールを必要とするので、どのタイプのデバッグを使用するかを選択することが可能です。 デフォルトでは、Android Studiosはプロジェクトで検出された言語に基づいて使用するデバッガーを決定します(Autoデバッガータイプの場合)。 ただし、デバッグ設定([実行]>[EditConfigurations]をクリック)または[実行]>[Attach debugger to Androidprocess]をクリックして表示されるダイアログで、デバッガーを手動で選択することができます。
利用可能なデバッグの種類は以下のとおりです。
Auto デバッグしているコードに最適なオプションを Android Studio に自動的に選択させたい場合は、このデバッグの種類を選択します。 たとえば、プロジェクトに C または C++ コードがある場合、Android Studio は自動的に Dual デバッグタイプを使用します。 それ以外の場合、Android StudioはJavaデバッグタイプを使用します。 Java JavaまたはKotlinで書かれたコードのみをデバッグする場合は、このデバッグタイプを選択します。Javaデバッガーは、ネイティブコードに設定したブレークポイントやウォッチを無視します。 Native (C/C++ コードでのみ使用可能) コードのデバッグに LLDB のみを使用する場合は、このデバッグタイプを選択します。 このデバッグタイプを使用する場合、Java デバッガーのセッションビューは使用できません。 デフォルトでは、LLDB はネイティブコードのみを検査し、Java コードのブレークポイントは無視されます。 Java コードもデバッグする場合は、Auto または Dual のいずれかのデバッグタイプに切り替えてください。
-
デバイスが
run-as
をサポートしているかどうかを確認するには、デバイスに接続されている ADB シェルで次のコマンドを実行します:run-as your-package-name pwd
your-package-name
をアプリケーションのパッケージ名に置き換えてください。 -
デバイスは
ptrace
を有効にしています。ptrace
が有効かどうかを確認するには、デバイスに接続したADBシェルで次のコマンドを実行します:sysctl kernel.yama.ptrace_scope
ptrace
が有効になっていれば、値0
またはunknown key
エラーを表示します。ptrace
が有効でない場合は、0
以外の値を表示します。
Dual (C/C++ コードでのみ使用可能) Java コードとネイティブコードの両方を切り替えてデバッグする場合は、このデバッグタイプを選択します。 Android Studio は Java デバッガーと LLDB の両方をアプリのプロセスにアタッチします。Java デバッガー用に 1 つ、LLDB 用に 1 つ、アプリを再起動したりデバッグ設定を変更したりせずに、Java コードとネイティブコードの両方でブレークポイントを検査することができます。
図 2 で、[Debug] ウィンドウのタイトルの右側にある 2 つのタブに注目してください。 アプリには Java と C++ の両方のコードがあるため、1 つのタブはネイティブ コードのデバッグ用で、もう 1 つは -java で示されるように Java コードのデバッグ用です。
図2. ネイティブコードのデバッグ用タブとJavaコードのデバッグ用タブ
注意:コンパイラで最適化されているネイティブコードをデバッグしている場合、以下の警告メッセージが表示されることがあります。 This function was compiled with optimizations enabled. Some debugger features may not be available
. -O
フラグのような最適化フラグを使用する場合、コンパイラーはより効率的に実行できるようにコンパイルされたコードに変更を加えます。 このため、最適化されたコンパイル済みコードを元のソースコードにマップすることが難しく、デバッガーが予期しない、または不正確な情報を報告することがあります。 このため、ネイティブ コードのデバッグ中は、コンパイラーの最適化を無効にする必要があります。
Use the system log
システム ログには、アプリケーションのデバッグ中にシステム メッセージが表示されます。 これらのメッセージには、デバイス上で実行されているアプリからの情報が含まれます。 システム ログを使用してアプリをデバッグする場合は、アプリが開発段階にある間に、コードがログ メッセージを書き込み、例外のスタックトレースを表示することを確認します。 ログ メッセージは、アプリケーションとの対話中にシステムのデバッグ出力を収集することにより、実行フローを理解するのに役立ちます。 ログメッセージは、アプリケーションのどの部分が失敗したかを教えてくれます。 ログの詳細については、「ログの書き込みと表示」を参照してください。
次の例では、アクティビティの開始時に以前の状態情報が利用可能かどうかを判断するために、ログ メッセージをどのように追加するかを示しています。
システム ログの表示
Logcat ウィンドウで、デバッグおよびその他のシステム メッセージを表示およびフィルターすることができます。 たとえば、ガベージコレクションが発生したときのメッセージや、Log
クラスでアプリに追加したメッセージを見ることができます。
logcat を使用するには、図 3 に示すように、デバッグを開始し、下部ツールバーで Logcat タブを選択します。
図3. Logcat ウィンドウとフィルター設定
ログキャットとそのフィルターオプションの説明については、「Logcat を使用してログを書き、表示する」を参照してください。 最も一般的なタイプは、コードの指定された行でアプリの実行を一時停止するラインブレークポイントです。 一時停止中に、変数を調べたり、式を評価したり、実行時エラーの原因を特定するために行ごとに実行を継続したりすることができます。
図3. ブレークポイントを設定すると、行の横に赤い点が表示されます
コードの実行がブレークポイントに達すると、Android Studioはアプリの実行を一時停止します。
-
変数のオブジェクト ツリーを調べるには、[変数] ビューでその変数を展開します。 変数]ビューが表示されていない場合は、[変数ビューを復元する]をクリックします。
-
現在の実行ポイントで式を評価するには、[式を評価する]をクリックします。
-
コードの次の行に進むには(メソッドを入力せずに)、[ステップオーバーする]をクリックします。
-
メソッド呼び出しの内部の最初の行に進むには、[Step Into]をクリックします。
-
現在のメソッドの外部の次の行に進むには、[Step Out]をクリックします。
-
アプリケーションを通常通りに実行するには、[プログラムの再開]をクリックします。
プロジェクトでネイティブ コードを使用している場合、デフォルトの Auto デバッグ タイプは Java デバッガーと LLDB の両方を 2 つの別々のプロセスとしてアプリにアタッチするので、アプリの再起動や設定の変更をせずに Java と C/C++ ブレークポイントを検査する間を切り換えることができます。 Android Studioが使用するデバッグタイプは、デバッグ設定を編集して変更することができます。 異なるデバッグタイプの詳細については、他のデバッグタイプの使用に関するセクションを参照してください。
Android Studio がターゲットデバイスにアプリを展開すると、図 4 に示すように、デバッグプロセスごとにタブまたはデバッグセッションビューで [デバッグ] ウィンドウが表示されます。 LLDB
- Android Studio は、LLDB デバッガーが C/C++ コードでブレークポイントを検出すると <your-module> タブに切り替わり、デバッグを開始します。 Frames、Variables、Watches ペインも使用でき、Java コードをデバッグしているときとまったく同じように機能します。 スレッド] ペインは LLDB セッション ビューでは使用できませんが、[フレーム] ペインのドロップダウン リストからアプリ プロセスにアクセスできます。 これらのペインについては、ウィンドウフレームのデバッグ方法と変数の検査方法のセクションで詳しく説明しています。
メモ: ネイティブコードのブレークポイントを検査している間、AndroidシステムはアプリのJavaバイトコードを実行する仮想マシンを一時停止します。 つまり、ネイティブコードでブレークポイントを検査している間は、Javaデバッガーと対話したり、Javaデバッガーセッションから状態情報を取得したりすることはできません。
- Android Studio は、Java デバッガーが Java コードでブレークポイントを検出すると <your-module>-java タブに切り替わります。
- LLDB によるデバッグ中に、LLDB セッション ビューの LLDB ターミナルを使用して、LLDB にコマンド ライン オプションを渡すことができます。 アプリのデバッグを開始するたびに、デバッガーがアプリのプロセスにアタッチする直前または直後に LLDB に実行させたい特定のコマンドがある場合、それらのコマンドをデバッグ構成に追加することができます。
C/C++ コードのデバッグ中に、ウォッチポイントと呼ばれる特別なタイプのブレークポイントを設定し、アプリが特定のメモリ ブロックとやり取りするときにアプリ プロセスを一時停止することも可能です。 詳細は、ウォッチポイントの追加方法に関するセクションを参照してください。
ブレークポイントの表示と設定
すべてのブレークポイントを表示したりブレークポイントの設定を構成するには、デバッグウィンドウの左側にあるブレークポイントの表示 をクリックします。 図5.
図5.ブレークポイント ウィンドウが表示されます。 ブレイクポイント] ウィンドウには現在のすべてのブレイクポイントが一覧表示され、それぞれの動作設定が含まれています
ブレイクポイント ウィンドウでは、左側の一覧から各ブレークポイントを有効または無効にすることができます。 ブレイクポイントが無効になっている場合、Android Studio はそのブレイクポイントにヒットしてもアプリを一時停止させません。 リストからブレークポイントを選択すると、その設定を行うことができます。 最初にブレークポイントを無効にし、別のブレークポイントにヒットした後にシステムが有効にするように設定することができます。 また、ブレークポイントにヒットした後、そのブレークポイントを無効にするかどうかの設定も可能です。 775>
デバッグ ウィンドウのフレーム
デバッガー ウィンドウのフレーム ペインでは、現在のブレークポイントをヒットさせたスタック フレームを検査することができます。 これにより、スタック フレームを移動して検査したり、Android アプリのスレッドのリストを検査したりすることができます。 スレッドを選択するには、スレッドセレクタのドロップダウンを使用し、そのスタックフレームを表示します。 フレーム内のエレメントをクリックすると、エディタでソースが開かれます。 Window Frames ガイドで説明したように、スレッドの表示をカスタマイズしたり、スタック フレームをエクスポートすることもできます。
Inspect variables
Debugger ウィンドウの Variables ペインでは、システムがブレークポイントでアプリを停止し、Frames ペインからフレームを選択すると、変数の検査が可能になります。 変数] ペインでは、静的メソッドおよび/または選択したフレーム内で利用可能な変数を使用して、その場限りの式を評価することもできます。
[監視] ペインは、[監視] ペインに追加した式がデバッグ セッション間で保持されることを除いて、同様の機能を提供します。 頻繁にアクセスする変数やフィールド、または現在のデバッグ セッションに役立つ状態を提供する変数やフィールドにウォッチを追加する必要があります。 変数と監視ペインは図5のように表示されます。
変数または式を監視リストに追加するには、次の手順に従います:
- デバッグを開始します。
- [ウォッチ]ペインで[追加]をクリックします。
- 表示されたテキストボックスに、ウォッチする変数または式の名前を入力し、Enterキーを押します。
[ウォッチ]リストから項目を削除するには、項目を選択して[削除].
をクリックします。項目を選択して[上へ]または[下へ].
図6.ウォッチリスト内の要素を並び替える デバッガウィンドウの変数とウォッチペイン
ウォッチポイントの追加
C/C++ コードのデバッグ中に、アプリケーションがメモリの特定のブロックとやり取りするときに、アプリケーションプロセスを中断できるウォッチポイントと呼ばれる特殊なブレークポイントを設定することができます。 たとえば、メモリのブロックに 2 つのポインターを設定し、それにウォッチポイントを割り当てた場合、メモリのブロックにアクセスするためにいずれかのポインターを使用すると、ウォッチポイントがトリガーされます。
Android Studio では、特定の変数を選択して実行時にウォッチポイントを作成できますが、LLDB は変数自体ではなく、システムがその変数に割り当てたメモリ ブロックにのみウォッチポイントを割り当てます。 これは、[ウォッチ] ペインに変数を追加して、変数の値を観察することはできますが、システムがメモリ内のその値を読み取ったり変更したりするときにアプリのプロセスを中断することはできないのとは異なります。
注意: アプリのプロセスが関数を終了して、システムがメモリからローカル変数を解放した場合、それらの変数に対して作成したウォッチポイントを再割り当てする必要があります。 デバイスが ARM CPU を使用している場合、メモリ内の変数のアドレスの境界を、32 ビット・プロセッサの場合は 4 バイトに、64 ビット・プロセッサの場合は 8 バイトに揃える必要があります。 以下のように、変数の減速に__attribute__((aligned(num_bytes)))
を指定することで、ネイティブコードで変数をアライメントできます:
// For a 64-bit ARM processorint my_counter __attribute__((aligned(8)));
注意: 32 ビット ARM ABI でアプリをデバッグする場合、ウォッチポイントを追加したり、コード内の変数にマウスを当ててその値を調べたりすると、クラッシュすることがあります。 回避策として、64-bit ARM、x86、または x86_64 のバイナリを使用してデバッグしてください。 この問題は、今後の Android Studio リリースで修正される予定です。
上記の要件を満たす場合、次のようにウォッチポイントを追加できます。
- アプリがブレークポイントで中断している間に、LLDB セッション ビューで変数ペインに移動してください。
-
追跡したいメモリ ブロックを占める変数を右クリックし、[ウォッチポイントの追加] を選択します。 図7に示すように、ウォッチポイントを設定するためのダイアログが表示されます。
図7. メモリ内の変数へのウォッチポイントの追加
- 以下のオプションでウォッチポイントを設定します。
- 有効にします。 当面の間、Android Studio にウォッチポイントを無視させたい場合は、このオプションの選択を解除できます。 Android Studioはウォッチポイントを保存するので、後でデバッグセッションでアクセスすることができます。
- サスペンド(Suspend)。 デフォルトでは、ウォッチポイントに割り当てられたメモリブロックにアクセスすると、Androidシステムはアプリプロセスを一時停止します。 この動作が不要な場合は、このオプションの選択を解除できます。このオプションを使用すると、システムがウォッチポイントとやり取りする際の動作をカスタマイズできます。 Log message to console and Remove when hit.
- アクセスタイプ: システムが変数に割り当てたメモリ ブロックに対して、アプリが読み取りまたは書き込みを行おうとしたときに、ウォッチポイントをトリガーするかどうかを選択します。 読み取りまたは書き込みのどちらかでウォッチポイントをトリガする場合は、[Any]を選択します。
- [Done]をクリックします。
すべてのウォッチポイントを表示したり、ウォッチポイントの設定を行うには、[デバッグ]ウィンドウの左側にある[ブレイクポイントの表示]をクリックします。 図8.
図8 ブレークポイント ダイアログが表示されます。 Breakpointsダイアログには現在のウォッチポイントが一覧表示され、それぞれの動作設定が含まれています
ウォッチポイントを追加したら、Debugウィンドウの左側にあるResume Program をクリックしてアプリのプロセスを再開してください。 デフォルトでは、アプリがウォッチポイントを設定したメモリブロックにアクセスしようとすると、Androidシステムはアプリのプロセスを一時停止し、図9に示すように、アプリが最後に実行したコード行の横にウォッチポイントのアイコン が表示されます(
図9.ウォッチポイントを設定したメモリブロックにアクセスしようとすると、Androidシステムはアプリのプロセスを一時停止し、最後に実行したコードの横にキャッチポイントのアイコン が表示されます)。 Android Studioは、アプリがウォッチポイントをトリガーする直前に実行したコード行を表示する
リソース値の表示と表示形式の変更
デバッグモードでは、リソース値を表示したり、Javaコード内の変数に対して異なる表示形式を選択したりすることが可能です。 変数]タブを表示し、フレームを選択した状態で、次の操作を行います。
- [変数]リストで、リソース行の任意の場所を右クリックして、ドロップダウン リストを表示します。
- ドロップダウン リストで[表示方法]を選択して、使用する形式を選択します。
使用可能な形式は、選択したリソースのデータ型によって異なります。 次のオプションのいずれか、または複数が表示される場合があります。 クラス定義を表示します。
- toString: 文字列の書式を表示します。
- Object: オブジェクト(クラスのインスタンス)の定義を表示する.
- Array: 配列形式で表示する.
- Timestamp: yyyy-mm-dd hh:mm:ss.
- Auto: Android Studioがデータ型に基づいて最適な形式を選択する.
- Binary: 日付と時刻を次のように表示する。 ゼロと1を使用したバイナリ値を表示します。
- MeasureSpec: 親から選択された子に渡される値です。
MeasureSpec
を参照してください。 - Hex: 16進数で表示します。
- Primitive: プリミティブなデータ型を使って数値で表示します。
- Integer:
以下のように、カスタムフォーマット(データ型レンダラ)を作成することができます。