‫ViewCapture در برنامه‌های سیستم

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

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

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

استفاده کردن

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

محدودیت‌ها

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

عملکرد

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

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

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

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

حافظه

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

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

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

  1. وابستگی را به فایل 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();
       }
        ...
      }