איך לוכדים פרופיל

בדף הזה מוסבר איך להקליט מעקב מערכת באמצעות ProfilingManager API.

הוספת יחסי תלות

כדי ליהנות מחוויית השימוש הטובה ביותר ב-ProfilingManager API, צריך להוסיף את ספריות Jetpack הבאות לקובץ build.gradle.kts.

Kotlin

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

מגניב

   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 כדי להגדיר את השרשור שיקבל את תוצאות הפרופיל. יצירת הפרופילים מתבצעת ברקע. שימוש ב-executor של שרשור שאינו שרשור UI עוזר למנוע שגיאות מסוג 'האפליקציה לא מגיבה (ANR)' אם מוסיפים עיבוד נוסף לקריאה החוזרת בהמשך.

  2. טיפול בתוצאות של יצירת פרופילים. יוצרים אובייקט Consumer<ProfilingResult>. המערכת משתמשת באובייקט הזה כדי לשלוח את תוצאות הפרופיל מ-ProfilingManager בחזרה לאפליקציה שלכם.

  3. יוצרים את בקשת הפרופיל. יוצרים SystemTraceRequestBuilder כדי להגדיר את סשן הפרופיל. הכלי הזה מאפשר לכם להתאים אישית את הגדרות המעקב של ProfilingManager. התאמה אישית של הכלי היא אופציונלית. אם לא מבצעים התאמה אישית, המערכת משתמשת בהגדרות ברירת המחדל.

    • הגדרת תג משתמשים ב-setTag() כדי להוסיף תג לשם של ה-trace. התג הזה עוזר לכם לזהות את המעקב.
    • אופציונלי: הגדרת משך הזמן. משתמשים ב-setDurationMs() כדי לציין את משך הפרופיל באלפיות השנייה. לדוגמה, 60000 מגדיר מעקב למשך 60 שניות. המעקב מסתיים אוטומטית אחרי משך הזמן שצוין אם לא מופעלת הפעולה CancellationSignal לפני כן.
    • בוחרים מדיניות של מאגר. משתמשים ב-setBufferFillPolicy() כדי להגדיר איך נתוני המעקב מאוחסנים. BufferFillPolicy.RING_BUFFER פירושו שכשהמאגר מלא, נתונים חדשים מחליפים את הנתונים הכי ישנים, וכך נשמרת רשומה רציפה של הפעילות האחרונה.
    • מגדירים את גודל המאגר. משתמשים ב-setBufferSizeKb() כדי לציין את גודל המאגר הזמני למעקב, שבעזרתו אפשר לשלוט בגודל של קובץ הפלט של המעקב.
  4. אופציונלי: ניהול מחזור החיים של הסשן. ליצור CancellationSignal. האובייקט הזה מאפשר לכם להפסיק את סשן יצירת הפרופיל מתי שתרצו, וכך לקבל שליטה מדויקת על משך הסשן.

  5. איך מתחילים ומקבלים תוצאות כשמתקשרים אל requestProfiling(),‏ ProfilingManager מתחיל סשן פרופילים ברקע. אחרי שהפרופיל מוכן, הוא נשלח לשיטת ProfilingResult שלכם ב-resultCallback#accept. אם יצירת הפרופיל מסתיימת בהצלחה, ProfilingResult מספק את הנתיב שבו השמירה של נתוני המעקב במכשיר בוצעה דרך ProfilingResult#getResultFilePath. אפשר לקבל את הקובץ הזה באופן פרוגרמטי או, ליצירת פרופיל מקומי, על ידי הפעלת הפקודה adb pull <trace_path> מהמחשב.

  6. הוספת נקודות מעקב בהתאמה אישית אפשר להוסיף נקודות מעקב מותאמות אישית לקוד של האפליקציה. בדוגמת הקוד הקודמת, פרוסת מעקב בשם MyApp:HeavyOperation נוספת באמצעות Trace.beginSection() ו-Trace.endSection(). הפרופיל שנוצר כולל את הפלח המותאם אישית הזה, שמדגיש פעולות ספציפיות באפליקציה.