プロファイルをキャプチャする方法

このページでは、ProfilingManager API を使用してシステム トレースを記録する方法について説明します。

依存関係を追加する

ProfilingManager API を最大限に活用するには、build.gradle.kts ファイルに次の Jetpack ライブラリを追加します。

Kotlin

   dependencies {
       implementation("androidx.tracing:tracing:1.3.0")
       implementation("androidx.core:core:1.16.0")
   }
   

Groovy

   dependencies {
       implementation 'androidx.tracing:tracing:1.3.0'
       implementation 'androidx.core:core:1.16.0'
   }
   

システム トレースを記録する

必要な依存関係を追加したら、次のコードを使用してシステム トレースを記録します。この例は、プロファイリング セッションを開始して管理するための Activity 内の基本的な設定を示しています。

Kotlin

@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
fun sampleRecordSystemTrace() {
    val mainExecutor: Executor =
        Dispatchers.IO.asExecutor() // Your choice of executor for the callback to occur on.
    val resultCallback = Consumer<ProfilingResult> { profilingResult ->
        if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
            Log.d(
                "ProfileTest",
                "Received profiling result file=" + profilingResult.resultFilePath
            )
        } else {
            Log.e(
                "ProfileTest",
                "Profiling failed errorcode=" + profilingResult.errorCode + " errormsg=" + profilingResult.errorMessage
            )
        }
    }
    val stopSignal = CancellationSignal()

    val requestBuilder = SystemTraceRequestBuilder()
    requestBuilder.setCancellationSignal(stopSignal)
    requestBuilder.setTag("FOO") // Caller supplied tag for identification
    requestBuilder.setDurationMs(60000)
    requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER)
    requestBuilder.setBufferSizeKb(20971520)
    requestProfiling(applicationContext, requestBuilder.build(), mainExecutor, resultCallback)

    // Wait some time for profiling to start.

    Trace.beginSection("MyApp:HeavyOperation")
    heavyOperation()
    Trace.endSection()

    // Once the interesting code section is profiled, stop profile
    stopSignal.cancel()
}

fun heavyOperation() {
    // Computations you want to profile
}

Java

void heavyOperation() {
  // Computations you want to profile
}

void sampleRecordSystemTrace() {
  Executor mainExecutor = Executors.newSingleThreadExecutor();
  Consumer<ProfilingResult> resultCallback =
      new Consumer<ProfilingResult>() {
        @Override
        public void accept(ProfilingResult profilingResult) {
          if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) {
            Log.d(
                "ProfileTest",
                "Received profiling result file=" + profilingResult.getResultFilePath());
          } else {
            Log.e(
                "ProfileTest",
                "Profiling failed errorcode="

                    + profilingResult.getErrorCode()
                    + " errormsg="
                    + profilingResult.getErrorMessage());
          }
        }
      };
  CancellationSignal stopSignal = new CancellationSignal();

  SystemTraceRequestBuilder requestBuilder = new SystemTraceRequestBuilder();
  requestBuilder.setCancellationSignal(stopSignal);
  requestBuilder.setTag("FOO");
  requestBuilder.setDurationMs(60000);
  requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER);
  requestBuilder.setBufferSizeKb(20971520);
  Profiling.requestProfiling(getApplicationContext(), requestBuilder.build(), mainExecutor,
      resultCallback);

  // Wait some time for profiling to start.

  Trace.beginSection("MyApp:HeavyOperation");
  heavyOperation();
  Trace.endSection();

  // Once the interesting code section is profiled, stop profile
  stopSignal.cancel();
}

サンプルコードは、次の手順でプロファイリング セッションを設定して管理します。

  1. エグゼキュータを設定します。Executor を作成して、プロファイリング結果を受け取るスレッドを定義します。プロファイリングはバックグラウンドで行われます。非 UI スレッド エグゼキュータを使用すると、後でコールバックに処理を追加する場合に、アプリケーション応答なし(ANR)エラーを防ぐことができます。

  2. プロファイリング結果を処理します。Consumer<ProfilingResult> オブジェクトを作成します。システムは、このオブジェクトを使用して、ProfilingManager からプロファイリング結果をアプリに返送します。

  3. プロファイリング リクエストを作成します。SystemTraceRequestBuilder を作成して、プロファイリング セッションを設定します。このビルダーを使用すると、ProfilingManager トレース設定をカスタマイズできます。ビルダーのカスタマイズは省略可能です。カスタマイズしない場合、システムはデフォルトの設定を使用します。

    • タグを定義します。setTag() を使用して、トレース名にタグを追加します。このタグはトレースの特定に役立ちます。
    • 省略可: 期間を設定します。setDurationMs() を使用して、プロファイリングの時間をミリ秒単位で指定します。たとえば、60000 は 60 秒のトレースを設定します。指定された期間が経過する前に CancellationSignal がトリガーされない場合、トレースは指定された期間が経過すると自動的に終了します。
    • バッファ ポリシーを選択します。setBufferFillPolicy() を使用して、トレースデータの保存方法を定義します。BufferFillPolicy.RING_BUFFER は、バッファが満杯になると、新しいデータが最も古いデータを上書きし、最近のアクティビティの連続した記録を保持することを意味します。
    • バッファサイズを設定します。setBufferSizeKb() を使用して、トレースのバッファサイズを指定します。このバッファサイズを使用して、出力トレース ファイルのサイズを制御できます。
  4. 省略可: セッションのライフサイクルを管理します。CancellationSignal を作成します。このオブジェクトを使用すると、いつでもプロファイリング セッションを停止できるため、セッションの長さを正確に制御できます。

  5. 開始して結果を受け取ります。requestProfiling() を呼び出すと、ProfilingManager がバックグラウンドでプロファイリング セッションを開始します。プロファイリングが完了すると、ProfilingResultresultCallback#accept メソッドに送信されます。プロファイリングが正常に終了すると、ProfilingResultProfilingResult#getResultFilePath を介して、トレースがデバイスに保存されたパスを提供します。このファイルは、プログラムで取得することも、ローカル プロファイリングの場合はパソコンから adb pull <trace_path> を実行して取得することもできます。

  6. カスタム トレースポイントを追加します。アプリのコードにカスタム トレースポイントを追加できます。前のコード例では、Trace.beginSection()Trace.endSection() を使用して MyApp:HeavyOperation という名前のトレース スライスを追加しています。このカスタム スライスは、生成されたプロファイルに表示され、アプリ内の特定のオペレーションがハイライト表示されます。