ViewCapture di aplikasi sistem

ViewCapture adalah alat software yang merekam properti tampilan (seperti lokasi, ukuran, skala, dan visibilitas) yang terlampir pada jendela yang terhubung dengannya. ViewCapture merekam 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.

Rekaman 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 kecil dan dapat diaktifkan lebih sering. Selain itu, ViewCapture menampilkan visualisasi frame demi frame di tingkat tampilan, sehingga lebih mudah untuk memeriksa status tampilan pada saat-saat tertentu dibandingkan dengan rekaman layar.

Halaman ini menjelaskan cara mengaktifkan ViewCapture di aplikasi sistem.

Gunakan

ViewCapture.java menerapkan instance onDrawListener dan mengumpulkan rekaman aktivitas ViewCapture selama proses penggambaran. Setiap penggambaran ulang frame memicu lintasan hierarki pohon tampilan yang dimulai dari tampilan root jendela. ViewCapture menggunakan metode getter 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 ini menjelaskan batasan performa dan memori ViewCapture.

Performa

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

Biaya operasional terutama disebabkan oleh tindakan berikut:

  1. Melintasi hierarki memerlukan biaya 50 μs, meskipun dipangkas.
  2. Mengambil objek dari pengalokasi daftar bebas untuk menyimpan salinan properti tampilan memerlukan biaya 20 μs.
  3. Mengambil setiap nilai properti melalui fungsi pengambil 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 batasan 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 dengan jejak memori yang telah ditentukan sebelumnya untuk mencegah penggunaan memori yang berlebihan. Pendekatan ini mencegah konsumsi memori yang berlebihan dengan menghindari penggunaan buffer cincin terpisah untuk setiap jendela. Namun, cara ini 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. Merekam lebih dari 30 jendela dari UI Sistem memerlukan buffer yang lebih besar atau waktu perekaman yang jauh lebih singkat.

Petunjuk

Untuk mengaktifkan ViewCapture di aplikasi sistem, ikuti petunjuk berikut:

  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 Anda, 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();
       }
        ...
      }