Hierarchy Viewer を使用してレイアウトをプロファイリングする

Hierarchy Viewer はサポートが終了しています。Android Studio 3.1 以降を使用している場合は、代わりに Layout Inspector を使用することで、アプリのビュー階層を実行時に検査できます。アプリのレイアウトのレンダリング速度をプロファイリングするには、Window.OnFrameMetricsAvailableListener を使用します。詳細については、こちらのブログ記事をご覧ください。

Hierarchy Viewer は、Android Device Monitor に組み込まれているツールで、レイアウト階層内の各ビューのレイアウト速度を測定できます。これにより、ビュー階層の構造に起因するパフォーマンス ボトルネックを発見できます。

注: Hierarchy Viewer はすでに開発が終了しています。代わりに Android Studio 内の Layout Inspector を使用して、ビュー階層のプロパティを実行時に検査するようにしてください。ただし、現在のところ、Layout Inspector では、レイアウト パフォーマンスに関するプロファイリングの詳細情報を入手することはできません。

このページでは、Hierarchy Viewer の概要を示し、レイアウトをプロファイリングする方法について説明します。

セットアップする

Android Emulator を使用している場合は、このセクションをスキップできます。そうでない場合は、以下のようにデバイスをセットアップする必要があります。

注: Android 4.1 以降を搭載しているデバイスを使用する必要があります。

  1. デバイスの開発者向けオプションを有効にします。
  2. 開発マシン上で、環境変数 ANDROID_HVPROTO=ddm を設定します。

    この変数は、DDMS プロトコルと同じ ddm プロトコルを使用してデバイスに接続するよう Hierarchy Viewer に指示します。ただし、デバイスに接続するホスト上には 1 つのプロセスしか存在できないため、Hierarchy Viewer を実行する際は、他の DDMS セッションを強制終了する必要があります。

Hierarchy Viewer を起動する

図 1. Android Device Monitor

  1. デバイスをパソコンに接続します。デバイス上に [USB デバッグを許可しますか?] と尋ねるダイアログが表示されたら、[OK] をタップします。
  2. Android Studio 内でプロジェクトを開き、デバイス上でビルドして実行します。
  3. Android Device Monitor を起動します。adb 経由でデバイスに接続できるのは同時に 1 つのプロセスだけに限られます。そのため、Android Device Monitor が接続をリクエストすると、Android Studio 内に [Disable adb integration] ダイアログが表示される場合があります。その場合は、[Yes] をクリックしてください。

    Android Device Monitor に最初に表示される状態を図 1 に示します。

  4. メニューバーで、[Window] > [Open Perspective] を選択して、[Hierarchy View] をクリックします。

    図 2 に示すようなパネル配置が表示されます。パネル配置が異なる場合は、[Window] > [Reset Perspective] を選択して、デフォルト レイアウトに戻してください。

  5. 左側の [Windows] タブで、アプリのパッケージ名をダブルクリックします。これにより、アプリのビュー階層がペインに表示されます。

ツールに慣れる

図 2. Hierarchy Viewer のパネル

Hierarchy Viewer には、以下のパネルがあります(図 2 を参照)。

  • Tree View(中央): ビュー階層のツリービューを表示します。マウスと下部にあるズーム コントロールを使用することで、ツリーをドラッグし、ズームできます。各ノードは、View クラス名と ID 名を示します。
  • Tree Overview(右上): アプリのビュー階層全体の概要を示します。グレーの長方形を移動すると、[Tree View] 内に表示されるビューポートを変更できます。
  • Layout View(右下): レイアウトのワイヤフレーム ビューを表示します。現在選択しているビューの輪郭は赤色で表示され、その親ビューは薄い赤色で表示されます。

    ここでビューをクリックすると、そのビューが [Tree View] 内で選択されます(逆も同様です)。

ビュー階層は、レイアウトのスナップショットであり、自動的には更新されません。階層ビューを更新するには、[Reload the view hierarchy]()をクリックします。

ビューを無効化する(次回のレイアウト更新時にシステムが onDraw() を呼び出すようにリクエストする)には、階層内のビューを選択して、[Invalidate the layout]()をクリックします(これは、ビューに対して invalidate() を呼び出すことと同じです)。ビュー(およびすべての子)を実際にレイアウトするようリクエストするには、[Request lay out]()をクリックします。

別のアプリに移動する場合は、左パネルにある [Windows] タブでそのアプリを選択して、ビュー階層を表示する必要があります。

指標やレイアウト、描画時間など、ビューの詳細を表示するには(図 3 を参照)、[Tree View] 内でそのビューをクリックします。ビューをダブルクリックすると拡大表示できます。

図 3. ビューノード表示部分

ビューのプロパティを表示するには、左パネルにある [View Properties] タブをクリックします(図 4 を参照)。

図 4. [View Properties] タブがある場所

レイアウトのレイヤ スクリーンショットを Adobe Photoshop(PSD)ファイルに保存するには、ツールバーのキャプチャ ウィンドウ レイヤ アイコン をクリックします。各ビューは独自のレイヤとして保存されるため、各ビューを非表示にして調整することで新しいモックを簡単に作成できます。

レイアウトをプロファイリングする

図 5. プロファイリング後のビュー階層

ツールの使用方法について理解したら、ツールを使用してビュー階層をプロファイリングして、結果を解釈します。

  1. [Tree View] または [Layout View] で、子をプロファイリングするビューノードをクリックします。
  2. プロファイリングを開始するには、[Tree View] の上部にある [Obtain layout times]()をクリックします。

    大きいビュー階層の場合、プロファイリングに数秒かかることがあります。

選択したノードの各子ビューには、緑色、黄色、または赤色のドットが 3 つ表示されます。

  • 左のドットは、レンダリング パイプラインの描画プロセスを示します。
  • 中央のドットは、レイアウト フェーズを示します。
  • 右のドットは、実行フェーズを示します。

図 6. 色付きドットと
レンダリング パイプラインの関係

各ドットは、それぞれ処理パイプラインの測定フェーズ、レイアウト フェーズ、描画フェーズにほぼ対応しています。ドットの色は、ローカル ファミリー内の他のすべてのプロファイル ノードを基準とした、このノードの相対的パフォーマンスを示します。

  • 緑色は、他のビューの少なくとも半分よりもレンダリングが速いことを意味します。
  • 黄色は、他のビューの下位半分よりもレンダリングが速いことを意味します。
  • 赤色は、下位半分のビューの中に含まれていることを意味します。

結果を解釈する

Hierarchy Viewer は、兄弟ビューと比較して各ノードのパフォーマンスを測定します。そのため、すべてのビューのパフォーマンスが完全に同一でない限り、プロファイル内には赤色のノードが常に存在します。赤色のノードのパフォーマンスが必ずしも悪いというわけではありません(ローカルビュー グループ内で最も遅いビューだというだけです)。

Hierarchy Viewer は、レイアウトをラスタライズしてタイミング情報を取得します。ラスタライズとは、円やベクター フォントといった高水準プリミティブを取得して、画面上のピクセルに変換するプロセスです。通常、ラスタライズはデバイスの GPU によって実行されますが、ソフトウェア ラスタライズの場合、レンダリングは、通常のソフトウェアを使用して CPU 上で実行されます。したがって、報告される絶対的タイミングは、相対的に正確なだけであり、デバイスと開発マシン上の全体的な CPU 負荷の変化に応じて変化します。デバイス上の実際のパフォーマンス速度を反映しているわけではないため、プロファイリングを複数回実行して平均測定値を取得するようにしてください。

赤色のノードは、想定を超えてアプリのパフォーマンスが低下した場合に問題となる可能性があります。相対的な設定では、最も遅いノードが常に存在します。想定どおりのノードであるか確認するようにしてください。赤色のドットの解釈方法について、以下に例を示します。

  • リーフノードや、少数の子しかないビューグループ内に赤色のドットがないか探します。この場合の赤色のドットは、問題を示している可能性があります。アプリの処理がもともと遅いとか、特定のデバイス上で遅くなるといったことはないと考えられますが、ドットが赤色になっている理由を把握する必要があります。SystraceTraceview を使用すると、追加情報を取得できます。
  • 多数の子があるビューグループで、赤色の測定フェーズがある場合は、それぞれの子のパフォーマンスを確認します。
  • ドットが黄色または赤色のビューでも、デバイス上での処理が遅くないこともあります。このような場合、実際の数値が役立ちます。SystraceTraceview を使用すると、追加情報を取得できます。
  • 階層のルートビューが赤色の測定フェーズ、赤色のレイアウト フェーズ、黄色の描画フェーズになっている場合は、おそらく問題ありません。他のすべてのビューの親であるため、すべての子がレイアウトを完了するまでレイアウトが完了せず、このような状況になります。
  • ビューが 20 以上あるツリー内のリーフノードに赤色の描画フェーズがある場合は、問題と考えられます。onDraw() メソッドを使用して、存在すべきではないコードが存在していないかチェックしてください。

レイアウトのヒントについては、レイアウト パフォーマンスを改善するをご覧ください。