Android Studio には、Androidエミュレーター上や接続されているAndroid端末上で動作しているアプリをデバッグできるデバッガーが搭載されています。 Android Studio デバッガーを使用すると、以下のことが行えます:
デバッグを開始するには、ツールバー上のDebug をクリックします。
するとAndroid StudioはAPKをビルドし、デバッグキーでAPKを署名し、選択した端末にAPKをインストールし、APKを実行して図1で示すように Debug ウィンドウを開きます。
C コードと C++ コードをプロジェクトに追加している場合、
Android StudioはDebugウィンドウ上でLLDB デバッガー も実行して、ネイティブコートのデバッグを行います。
DebugをクリックしてもSelect Deployment Targetウィンドウに端末が表示されない場合は、 端末を接続するか、Create New Emulator をクリックしてAndroid エミュレーターを設定する必要があります。
図 1. 現在のスレッドと変数のオブジェクトツリーを表示しているデバッグウィンドウ。
接続された端末上やエミュレータ上で既にアプリが動作している場合、以下のようにしてデバッグを開始することができます:
既定では、デバッガーは現在のプロジェクトの端末とアプリプロセスの他に、接続されたハードウェア端末やコンピュータ上の仮想端末も表示します。 全ての端末上の全てのプロセスを表示するには、 Show all processes を選びます。; 例えば、画面にはアプリが作成したサービスの他にシステムのプロセスも表示されます。
Debugger メニューから、別のデバッグタイプを選ぶことができます。 既定ではAndroid Studio は デバッグタイプAutoを使って、プロジェクトにJava コードやC/C++コードが含まれているかどうかに基づき、あなたにとって最適なデバッガーオプションを選びます。
Debug ウィンドウが表示されます。今回の場合、デバッグウィンドウのタイトルの右にある二つのタブに注意してください:一つのタブはネイティブコードをデバッグするためのもので、もう一つのタブは(-javaと示されている通り)Java コードをデバッグするためのものです。
それぞれのデバッグセッションごとに個別のタブと異なるポート番号を持っています。ポート番号は、タブの括弧内に表示されています。
メモ: Android Studio デバッガーとガベージコレクションは疎結合の関係です。
Android 仮想マシンでは、デバッガーが切断されるまではデバッガーが認識しているオブジェクトをガベージコレクトしないことが保証されています。
これにより、デバッガーが接続されている間は時間経過に伴ってオブジェクトが蓄積される可能性があります。
例えば、デバッガーが実行中のスレッドを認識している場合は、関連するThread
オブジェクトはそのスレッドが終了した後でさえガベージコレクトされません。
既定では、 Android Studio はデバッグタイプAutoを使って使用するデバッガーを決めるので、Java コードとC/C++コードのデバッグを切り替える時に設定を変更する必要はありません。しかし、 デバッグ設定の作成や編集を行って特定の設定をカスタマイズ(シンボルディレクトリやLLDBコマンドの追加、別のデバッグ対応の使用など)することができます。 デバッガーを実行中のAndroid プロセスに接続する時、Choose Processダイアログ内の Debugger ドロップダウンリストからデバッグタイプを選ぶこともできます。
使用可能なデバッグタイプは以下の通りです:
メモ: Android Studio には、一つのLLDBプロセスを使ってJavaとC/C++両方のブレークポイントをデバッグすることができる、実験段階のJava対応C++デバッガー機能が用意されています。 この機能はまだ開発中ですが、 Android Studio 2.2以上では自己責任で試してみることができます。 詳細について学ぶには、 Android ツールのウェブサイトを参照してください。
アプリをデバッグしている間、システムログにはシステムメッセージが表示されます。 これらのメッセージには、端末上で動作しているから届いた情報が含まれています。 システムログを使ってアプリをデバッグしたい場合は、アプリの開発段階で、コード上からログメッセージに書き込みを行い、例外のスタックトレースを出力するようにしてください。
コード上からログメッセージに書き込みを行うには、Log
クラスを使用します。
Log メッセージを使えば、アプリの操作中にシステムのデバッグ出力を収集することで、実行フローを理解するのに役立ちます。
Log メッセージは、アプリのどの部分でエラーが発生したかを教えてくれます。
ログ機能の詳細については、ログの読み込みと書き込みを参照してください。
以下の例では、ログメッセージを追加して、アクティビティ起動時に前回の状態情報を使用可能かどうかを判別する方法を例示しています。:
import android.util.Log; ... public class MyActivity extends Activity { private static final String TAG = MyActivity.class.getSimpleName(); ... @Override public void onCreate(Bundle savedInstanceState) { if (savedInstanceState != null) { Log.d(TAG, "onCreate() Restoring previous state"); /* restore state */ } else { Log.d(TAG, "onCreate() No saved state available"); /* initialize app */ } } }
開発時に、例外をキャッチしてスタックトレースをシステムログに書き込むこともできます。:
void someOtherMethod() { try { ... } catch (SomeException e) { Log.d(TAG, "someOtherMethod()", e); } }
メモ: アプリを公開する準備が出来から、デバッグログの処理とスタックトレース出力の処理をコード上から削除します。
これは、DEBUG
フラグを設定してデバッグログメッセージを条件文の中に入れることで行えます。
Android DDMS (Dalvik Debug Monitor Server)と Android Monitorウィンドウは両方とも、システムや特定のアプリプロセスから取得したログを表示します。 Android DDMSツールウィンドウでシステムログを見るには:
図 2. Android DDMS ツールウィンドウ上でのシステムログ。
Android DDMS ツールウィンドウを使うことで、Android Studio上からいくつかのDDMS 機能にアクセスすることができます。 DDMSの詳細については、DDMSを使用するを参照してください。
システムログは、Android サービスやその他Android アプリから取得したメッセージを表示します。 メッセージログをフィルターして興味のあるもののみを表示するには、 Android DDMSウィンドウ上でツールを使用します。:
Android Studio では、様々なデバッグ動作を引き起こす、複数のタイプのブレークポイントをサポートしています。 最も一般的なタイプは、指定されたコード行でアプリの実行を一時停止させる、行ブレークポイントです。 一時停止している間に変数を検査して式を評価し、一行ずつコードの実行をし続けてランタイムエラーの原因を特定します。
行ブレークポイントを追加するには、以下のように作業します:
図 3. ブレークポイントを設定した時、その行の隣に赤ドットが表示されます。
コードの実行がブレークポイントまで達した時、Android Studioはアプリの実行を一時停止します。 その後、Debugger タブ内にあるツールを使ってアプリの状態を識別できます:
変数のオブジェクトツリーを調査するには、Variablesビュー上でその変数を展開します。
Variablesビューが表示されない場合は、Restore Variables View
をクリックします。
現在の実行ポイントでの式を評価するには、Evaluate Expression をクリックします。
コード上の次の行へ進むには(メソッドを入力せずに)、Step Over をクリックします。
メソッド呼び出し内の最初の行へ進むには、Step
Into をクリックします。
現在のメソッド外の次の行へ進むには、 Step
Out をクリックします。
アプリの実行を通常通り続けるには、Resume Program
をクリックします。
プロジェクトでネイティブコードを使用している場合、既定ではデバッグタイプ AutoだとJava デバッガーとLLDB の両方を二つの別々のプロセスとしてアプリに接続するので、 アプリの再起動や設定変更をしなくても、Java とC/C++それぞれのブレークポイントの検査を切り替えることができます。
メモ: Android Studio でC や C++ のコード上にあるブレークポイントを検出するには、AutoやNativeやHybridのようなLLDBをサポートしているデバッグタイプを使用する必要があります。 デバッグ設定を編集することで、 Android Studioが使用するデバッグタイプを変更することができます。 様々なデバッグタイプについてより学ぶには、他のデバッグタイプの使用に関する項目を参照してください。
Android Studio が対象の端末にアプリをデプロイした時、図4で示すように、タブやデバッグセッションビューの付いたDebug ウィンドウが各デバッグプロセスごとに開きます。
図 4. LLDBを使用してネイティブコードをデバッグする。
メモ: ネイティブコード上のブレークポイントを調査している間、Android システムは、アプリのJavaバイトコードを実行している仮想マシンを一時停止させます。 つまり、ネイティブコード上のブレークポイントを調査している間は、Javaデバッガーの操作やJavaデバッガーからの状態情報取得は行えません。
ヒント: アプリのデバッグを開始する度にLLDB に特定のコマンドを実行させたい場合、デバッガーがアプリプロセスに接続する直前または直後のいずれかに、 そうしたコマンドをデバッグ設定に追加することができます。
C/C++ コードをデバッグする際には、 ウォッチポイントと呼ばれる特別なタイプのブレークポイントを設定することもできます。 これは、アプリが特定のメモリーブロックを操作したタイミングでアプリプロセスを一時停止することができます。 詳細を学ぶには、 ウォッチポイントを追加する方法に関する項目を参照してください。
全てのブレークポイントを表示してブレークポイント構成を設定するには、
Debugウィンドウの左側にあるView Breakpoints をクリックします。
Breakpoints ウィンドウは、図5のように表示されます。
図 5. Breakpoints ウィンドウは現在の全てのブレークポイントを一覧表示し、それぞれの動作設定も表示します。
Breakpoints ウィンドウでは、左側の一覧から各ブレークポイントを有効にした無効にしたりできます。 ブレークポイントが無効の場合、そのブレークポイントにヒットしたとしてもAndroid Studioはアプリを一時停止させません。 ブレークポイントの設定を行うには、一覧からそのブレークポイントを選んでください。 ブレークポイントを最初は無効にしておいて、他のブレークポイントにヒットしたら有効になるようにシステムを設定することができます。 例外用のブレークポイントを設定するには、ブレークポイント一覧から Exception Breakpoints を選びます。
Debugger ウィンドウ内で、Frames パネルを使って、現在のブレークポイントにヒットした原因のスタックフレームを調査することができます。 これにより、スタックフレーム内を移動して調査を行い、Android アプリのスレッドの一覧を検査することもできます。 スレッドを選択するには、thread selectorドロップダウンメニューを使ってそのスタックフレームを表示します。 フレーム内で要素をクリックすると、エディター上でそのソースが開きます。 またFrames パネルの案内で説明しているように、スレッドの見栄えをカスタマイズしたりスタックフレームをエクスポートしたりできます。
Debugger ウィンドウ内のVariables パネルでは、システムがブレークポイントでアプリを停止させた時に変数を検査したり、 Framesパネルからフレームを選んだりできます。 また Variables パネルでは、選択したフレーム内で使用可能な静的メソッドや変数、もしくはその両方を使ってアドホック式を評価することもできます。
Watchesパネルでも、 Watchesパネルに追加された式はデバッグセッション中は維持され続けるという点を除いて、 Variablesパネルとほぼ同じ機能があります。 頻繁にアクセスしたり、現在のデバッグセッションで役立つ情報を持ってたりする変数やフィールドは、watches パネルに追加するようにしてください。 Variables パネルとWatches パネルは、図5のように表示されます。
変数や式を Watches 一覧に追加するには、以下の手順に沿って作業をしてください:
Watches 一覧から項目を削除するには、その項目を選んでRemove をクリックします。
項目を選択して Up や Down
をクリックすることで、Watches一覧の要素の順序を変更することができます。
図 6. Debuggerウィンドウ内のVariables パネルとWatches パネル。
C/C++ コードをデバッグする際には、 ウォッチポイントと呼ばれる特別なタイプのブレークポイントを設定することができます。 これは、アプリが特定のメモリーブロックを操作したタイミングでアプリプロセスを一時停止することができます。 例えば、メモリーブロックに二つのポインターを設定してそれにウォッチポイントを割り当てた場合、 そのポインターのうちどちらかを使ってメモリーブロックにアクセスするとウォッチポイントが引き起こされます。
Android Studioでは、特定の変数を選択することで実行中にウォッチポイント作成できますが、 LLDB はシステムがその変数に割り当てるメモリブロックにのみウォッチポイントを割り当てます。 変数自体にウォッチポイントを割り当てるわけではありません。 これは、変数をWatchesパネルに追加するのとは異なります。 変数をWatchesパネルに追加した場合、変数の値を監視することはできますが、システムがそのメモリの値を読み込んだり変更したりした時にアプリプロセスを一時停止させることはできません。
メモ:アプリプロセスが関数を終了して、システムがそのローカル関数をメモリから解放した時、それら変数用に作成したウォッチポイントを再割り当てする必要があります。
ウォッチポイントを設定するには、以下の要件を満たす必要があります:
__attribute__((aligned(num_bytes)))
を設定することで、ネイティブコード上で変数を揃えることができます。:
// For a 64-bit ARM processor int my_counter __attribute__((aligned(8)));
上記要件を満たした場合、以下のようにしてウォッチポイントを追加できます:
追跡したいメモリブロックを占有する変数を右クリックし、Add Watchpointを選びます。 図7で示すように、ウォッチポイントを設定するためのダイアログが表示されます。
図 7. メモリ上の変数にウォッチポイントを追加する。
全てのウォッチポイントを表示し、ウォッチポイントの設定を行いには、Debugウィンドウの左側にあるView Breakpoints をクリックします。
図8で示すように、Breakpoints ダイアログが表示されます。
図 8. Breakpoints ダイアログでは現在のウォッチポイントを一覧表示し、それぞれの動作設定も表示します。
ウォッチポイントを追加したら、Debugウィンドウの左側にあるResume Program をクリックしてアプリプロセスを再開します。
既定では、ウォッチポイントを設定したメモリーブロックにアプリがアクセスしようとした場合、Android プロセスはアプリを一時停止させて、図9で示すようにウォッチポイントアイコン (
)を最後に実行されたコード行の隣に表示します。
図 9. Android Studio は、ウォッチポイントが引き起こされる直前にアプリが実行したコード行を示します。
Android Studioでは、Java ヒープで割り当てられたオブジェクトを追跡し、これらのオブジェクトを割り当ててるクラスやスレッドを確認できます。 これにより、任意の期間に割り当てられたオブジェクトの一覧を確認することができます。 この情報は、アプリのパフォーマンスに影響を与えるようなメモリ使用を評価するのに役立ちます。
Android モニターには、アプリケーションのメモリー, CPU,GPU, Network 使用状況に関する情報が表示されます。 Android モニターに使用方法に関する詳細は、Android モニターの基本を参照してください。 また、ロギングカタログ(logcat)、パフォーマンスモニター、データ分析ツール、画面と動画のキャプチャツールを含むAndroid Monitorの機能に関する説明は、 Android モニターの概要 を参照してください。
図 10.Android Studio上でのオブジェクト割り当てトラッキング
デバッグモードでは、リソース値を表示したり別の表示形式を選ぶことができます。 Variables タブが表示されてフレームが選択された状態で、以下を行います:
使用可能な形式は、あなたが選んだリソースのデータタイプによって異なります。以下のオプションのうち一つ、または複数が表示されます:
MeasureSpec
を参照してください。Integer
型の数値を表示します。以下のようにして、カスタム形式 (データタイプレンダラー)を作成できます。:
アプリケーションでランタイムエラーが発生しなかったとしても、それで問題がないというわけではありません。以下のような問題も考慮する必要があります。:
Android デバイスモニターは、いくつかのAndroid アプリケーションデバッグツールと分析ツール用のグラフィカルなユーザーインタフェースを備えた、独立したツールです。 ツールには、Dalvik Debug Monitor Server (DDMS)などがあります。 Android デバイスモニターを使って、メモリ使用状況の分析、メソッドのプロファイル、ネットワークトラフィックの監視、コール着信とメッセージ受信の再現を行うことができます。
Android Studioから,Android デバイスモニターを開くには、
ツールバーにあるMonitor をクリックします。
Android デバイスモニターが新規ウィンドウで開きます。
Android デバイスモニターと DDMSの詳細については、 デバイスモニター と DDMSを使用するを参照してください。
Android Studio を使うと、アプリを実行している間の端末が面のスクリーンショットや短い動画を取得することができます。 スクリーンショットと動画はアプリのプロモーション素材として役立ち、また開発チームに送るバグレポートにそれらを付けることもできます。
アプリのスクリーンショットを取得するには:
アプリの動画を取得するには: