ViewCapture di aplikasi sistem

ViewCapture adalah alat software yang mengambil properti tampilan (seperti lokasi, ukuran, skala, dan visibilitas) yang dilampirkan ke jendela yang dihubungkan kepadanya. ViewCapture mengambil informasi tentang berbagai tampilan dalam jendela dan propertinya, sehingga Anda dapat mengetahui status pengalaman pengguna pada waktu tertentu dan melacak perubahan dari waktu ke waktu.

Perekaman layar dapat memvisualisasikan status tampilan pada waktu tertentu dan menunjukkan perubahannya, tetapi memerlukan resource CPU yang signifikan dan dapat memengaruhi performa. Alat ViewCapture memiliki dampak resource yang lebih sedikit dan dapat diaktifkan lebih sering. Selain itu, ViewCapture menampilkan visualisasi frame demi frame di tingkat tampilan, sehingga lebih mudah untuk memeriksa status tampilan pada momen tertentu dibandingkan dengan perekaman layar.

Halaman ini menjelaskan cara melakukan aktivasi ViewCapture di aplikasi sistem.

Gunakan

ViewCapture.java menerapkan instance onDrawListener dan mengumpulkan pelacakan ViewCapture selama proses menggambar. Setiap penggambaran ulang frame memicu perjalanan hierarki hierarki tampilan yang dimulai dari tampilan root jendela. ViewCapture menggunakan metode pengambil View.java publik untuk mengambil dan menyalin nilai ke thread latar belakang untuk meningkatkan performa. Implementasi ViewCapture mengoptimalkan proses ini dengan memeriksa apakah tampilan kotor atau tidak valid menggunakan captureViewTree, sehingga menghindari penelusuran seluruh hierarki tampilan. captureViewTree hanya tersedia untuk aplikasi sistem dan merupakan bagian dari UnsupportedAppUsage API. Penggunaan API ini terbatas untuk aplikasi berdasarkan versi SDK targetnya.

Batasan

Bagian berikut menjelaskan batasan performa dan memori dalam menjalankan ViewCapture.

Performa

Overhead thread utama rata-rata untuk performa ViewCapture adalah 195 μs. Namun, dalam skenario terburuk, perlu waktu sekitar 5 milidetik. Lihat slice vc#onDraw dalam rekaman aktivitas Perfetto.

Biaya overhead terutama disebabkan oleh tindakan berikut:

  1. Melintasi hierarki memerlukan waktu 50 μs, meskipun dipangkas.
  2. Menarik objek dari alokator freelist untuk menyimpan salinan properti tampilan memerlukan waktu 20 μs.
  3. Mengambil setiap nilai properti melalui fungsi pengambil akan menghasilkan banyak panggilan fungsi tambahan per tampilan, yang menghabiskan waktu 110 μs.

Oleh karena itu, mengaktifkan ViewCapture dalam pelacakan selalu aktif (AOT) berdampak negatif pada performa sistem dan menyebabkan jank. Karena keterbatasan performa dan memori ini, pendekatan ini belum siap untuk AOT. Sebaiknya gunakan ViewCapture hanya untuk lab dan proses debug lokal.

Memori

Metode Perfetto untuk rekaman aktivitas ViewCapture menggunakan satu buffer ring, yang memiliki jejak memori yang telah ditentukan untuk mencegah penggunaan memori yang berlebihan. Pendekatan ini mencegah konsumsi memori yang berlebihan dengan menghindari penggunaan buffering ring terpisah untuk setiap jendela, tetapi tidak menyelesaikan masalah penyimpanan seluruh hierarki tampilan untuk setiap status di Perfetto untuk setiap frame. Merekam satu jendela, seperti NexusLauncher, dapat menghasilkan data ViewCapture lebih dari 30 detik dalam buffer 10 MB. Namun, merekam lebih dari 30 jendela dari UI Sistem memerlukan buffer yang lebih besar atau periode waktu perekaman yang jauh lebih singkat.

Petunjuk

Ikuti petunjuk berikut untuk mengaktifkan ViewCapture di aplikasi sistem:

  1. Tambahkan dependensi ke file Android.bp Anda, seperti yang ditunjukkan dalam Kode peluncur.

    android_library {
        name: "YourLib",
        static_libs: [
              ...
            "//frameworks/libs/systemui:view_capture",
              ...
        ],
        platform_apis: true,
        privileged: true,
    }
    
  2. Buat instance ViewCapture saat membuat jendela, misalnya:

    • Contoh 1:

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
      }
      
    • Contoh 2:

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (enableViewCaptureTracing()) {
            mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
              .startCapture(getRootView(), ".NotificationShadeWindowView");
        }
        ...
      }
      
  3. Tutup instance ViewCapture saat menghancurkan jendela, seperti yang ditunjukkan dalam contoh berikut:

    • Contoh 1:

      @Override
      public void onDestroy() {
        ...
        if (mViewCapture != null) mViewCapture.close();
      }
      
    • Contoh 2:

      @Override
      protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mViewCaptureCloseable != null) {
            mViewCaptureCloseable.close();
       }
        ...
      }