ViewCapture در برنامه های سیستمی، ViewCapture در برنامه های سیستمی

ViewCapture ابزاری نرم‌افزاری است که ویژگی‌های نماها (مانند مکان، اندازه، مقیاس و میزان دید) متصل به پنجره‌هایی که به آنها متصل است را ثبت می‌کند. ViewCapture اطلاعاتی در مورد نماهای مختلف درون یک پنجره و ویژگی‌های آنها ثبت می‌کند و به شما این امکان را می‌دهد که از وضعیت تجربه کاربری در لحظات خاص زمانی مطلع شوید و تغییرات را در طول زمان پیگیری کنید.

ضبط صفحه نمایش می‌تواند وضعیت یک نما را در یک زمان خاص تجسم کند و نحوه تغییرات آن را نشان دهد، اما به منابع قابل توجهی از پردازنده نیاز دارد و می‌تواند بر عملکرد تأثیر بگذارد. ابزار ViewCapture تأثیر کمتری بر منابع دارد و می‌تواند بیشتر فعال شود. علاوه بر این، ViewCapture تصاویر را فریم به فریم در سطح نما نمایش می‌دهد و بررسی وضعیت نما را در لحظات خاص در مقایسه با ضبط صفحه نمایش ساده‌تر می‌کند.

این صفحه نحوه‌ی فعال‌سازی ViewCapture در برنامه‌های سیستمی را شرح می‌دهد.

استفاده کنید

ViewCapture.java نمونه‌ای از onDrawListener را پیاده‌سازی می‌کند و در طول فرآیند ترسیم، رد ViewCapture را جمع‌آوری می‌کند. هر ترسیم مجدد فریم، پیمایش سلسله مراتب درخت نما را از نمای ریشه پنجره آغاز می‌کند. ViewCapture از متدهای عمومی View.java getter برای واکشی و کپی کردن مقادیر در یک نخ پس‌زمینه برای بهبود عملکرد استفاده می‌کند. پیاده‌سازی ViewCapture این فرآیند را با بررسی کثیف یا نامعتبر بودن یک نما با استفاده از captureViewTree بهینه می‌کند و در نتیجه از پیمایش کل سلسله مراتب نما جلوگیری می‌کند. captureViewTree فقط برای برنامه‌های سیستمی در دسترس است و بخشی از API UnsupportedAppUsage است. استفاده از این API محدود به برنامه‌ها بر اساس نسخه SDK هدف آنها است.

محدودیت‌ها

این بخش، عملکرد و محدودیت‌های حافظه‌ی ViewCapture را شرح می‌دهد.

عملکرد

میانگین سربار نخ اصلی برای عملکرد ViewCapture برابر با ۱۹۵ میکروثانیه است. با این حال، در بدترین حالت، می‌تواند تقریباً ۵ میلی‌ثانیه طول بکشد. به برش vc#onDraw در نمودار Perfetto مراجعه کنید.

هزینه‌های سربار عمدتاً ناشی از اقدامات زیر است:

  1. پیمایش سلسله مراتب، حتی در صورت هرس شدن، 50 میکروثانیه هزینه دارد.
  2. استخراج اشیاء از یک تخصیص‌دهنده‌ی لیست آزاد برای ذخیره‌ی کپی‌هایی از ویژگی‌های نما، 20 میکروثانیه هزینه دارد.
  3. دریافت هر مقدار ویژگی از طریق یک تابع getter منجر به فراخوانی‌های تابع اضافی زیادی به ازای هر نما می‌شود که ۱۱۰ میکروثانیه هزینه دارد.

از این رو، فعال کردن ViewCapture در حالت Always-on-tracing (AOT) تأثیر منفی بر عملکرد سیستم می‌گذارد و منجر به jank می‌شود. با توجه به این محدودیت‌های عملکرد و حافظه، این رویکرد برای AOT آماده نیست. ما ViewCapture را فقط برای اشکال‌زدایی آزمایشگاهی و محلی توصیه می‌کنیم.

حافظه

روش Perfetto برای ردیابی ViewCapture از یک بافر حلقه‌ای واحد با ردپای حافظه از پیش تعریف‌شده برای جلوگیری از استفاده بیش از حد از حافظه استفاده می‌کند. این رویکرد با اجتناب از بافرهای حلقه‌ای جداگانه برای هر پنجره، از مصرف بیش از حد حافظه جلوگیری می‌کند. با این حال، مشکل ذخیره کل سلسله مراتب نمایش برای هر حالت در Perfetto برای هر فریم را حل نمی‌کند. ضبط یک پنجره واحد، مانند NexusLauncher، می‌تواند بیش از 30 ثانیه داده ViewCapture را در یک بافر 10 مگابایتی تولید کند. ضبط بیش از 30 پنجره از رابط کاربری سیستم یا به بافر بزرگتری نیاز دارد یا زمان ضبط به طور قابل توجهی کوتاه‌تر می‌شود.

دستورالعمل‌ها

برای فعال کردن ViewCapture در برنامه‌های سیستمی، این دستورالعمل‌ها را دنبال کنید:

  1. همانطور که در کد Launcher نشان داده شده است، وابستگی را به فایل Android.bp خود اضافه کنید.

    android_library {
        name: "YourLib",
        static_libs: [
              ...
            "//frameworks/libs/systemui:view_capture",
              ...
        ],
        platform_apis: true,
        privileged: true,
    }
    
  2. هنگام ایجاد پنجره، یک نمونه ViewCapture ایجاد کنید، برای مثال:

    • مثال ۱ :

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
      }
      
    • مثال ۲ :

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (enableViewCaptureTracing()) {
            mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
              .startCapture(getRootView(), ".NotificationShadeWindowView");
        }
        ...
      }
      
  3. هنگام از بین بردن پنجره، نمونه ViewCapture را ببندید، همانطور که در مثال‌های زیر نشان داده شده است:

    • مثال ۱ :

      @Override
      public void onDestroy() {
        ...
        if (mViewCapture != null) mViewCapture.close();
      }
      
    • مثال ۲ :

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