ViewCapture في تطبيقات النظام

‫ViewCapture هي أداة برامج تلتقط سمات المرئيات (مثل الموقع الجغرافي والحجم والنسبة المئوية للعرض) المرتبطة بالنوافذ التي تم ربطها بها. تلتقط ميزة ViewCapture معلومات عن طرق العرض المختلفة ضمن نافذة وسماتها، ما يتيح لك معرفة حالة تجربة المستخدِم في لحظات معيّنة من الوقت وتتبُّع التغييرات بمرور الوقت.

يمكن أن تُظهر تسجيلات الشاشة حالة العرض في وقت معيّن وتوضّح كيفية تغيُّرها، ولكنّها تتطلّب موارد كبيرة من وحدة المعالجة المركزية ويمكن أن تؤثر في الأداء. تؤثر أداة ViewCapture في الموارد بشكلٍ أقل، ويمكن تفعيلها بوتيرة أكبر. بالإضافة إلى ذلك، يعرض ViewCapture الرسومات البيانية إطارًا تلو الآخر على مستوى العرض، ما يسهّل فحص حالة العرض في لحظات معيّنة مقارنةً بتسجيلات الشاشة.

توضّح هذه الصفحة كيفية إعداد ViewCapture في تطبيقات النظام.

استخدام

ينفِّذ ViewCapture.java مثيلًا من onDrawListener ويجمع تتبع ViewCapture أثناء عملية الرسم. يؤدي إعادة رسم كل إطار إلى التنقّل في التسلسل الهرمي لشجرة العرض بدءًا من العرض الجذر للنافذة. يستخدم ViewCapture طرق الحصول العامة على View.java لاسترداد القيم ونسخها إلى سلسلا رسائل في background لتحسين الأداء. يعمل تنفيذ ViewCapture على تحسين هذه العملية من خلال التحقّق مما إذا كان العرض غير صالح أو غير محدّث باستخدام captureViewTree، وبالتالي تجنُّب التنقّل في التسلسل الهرمي الكامل للعرض. لا يتوفّر captureViewTree سوى لتطبيقات النظام، وهو جزء من واجهة برمجة التطبيقات UnsupportedAppUsage API. يقتصر استخدام واجهة برمجة التطبيقات هذه على التطبيقات استنادًا إلى إصدار حزمة SDK المستهدَف.

القيود

توضّح الأقسام التالية قيود الأداء والذاكرة في تشغيل ميزة ViewCapture.

الأداء

متوسّط الوقت المستغرَق في سلسلة المحادثات الرئيسية لأداء ViewCapture هو 195 μs. ومع ذلك، في أسوأ السيناريوهات، يمكن أن يستغرق ذلك 5 ملي ثانية تقريبًا. يُرجى الرجوع إلى شريحة vc#onDraw في أثر Perfetto.

تعود التكاليف الإضافية بشكل أساسي إلى الإجراءات التالية:

  1. تبلغ تكلفة التنقّل في التسلسل الهرمي 50 μs، حتى في حال اقتصاصه.
  2. إنّ سحب العناصر من أداة تخصيص القائمة الحرة لتخزين نُسخ من سمات العرض يتطلّب 20 μs.
  3. يؤدي جلب كل قيمة خاصية من خلال دالة جلب إلى العديد من طلبات الدالة الإضافية لكلّ عرض، ما يتطلّب 110 μs.

وبالتالي، يؤثّر تفعيل ViewCapture في ميزة "التتبّع الدائم" (AOT) سلبًا في أداء النظام ويؤدي إلى حدوث تقطُّع في الأداء. بسبب هذه القيود المفروضة على الأداء والذاكرة، لا يكون هذا النهج جاهزًا للترجمة المسبقة للوقت. ننصح باستخدام ViewCapture فقط في المختبر و لتصحيح الأخطاء على الجهاز فقط.

الذاكرة

تستخدِم طريقة Perfetto لتتبُّع ViewCapture مخزنًا دائريًا واحدًا، الذي يحتوي على مساحة تخزين محددة مسبقًا للذاكرة لمنع استخدام الذاكرة بشكل مفرط. يمنع هذا الأسلوب استهلاك الذاكرة بشكلٍ مفرط عن طريق تجنُّب استخدام ملف ذاكرة مؤقت دوار منفصل لكل نافذة، ولكنه لا يحلّ مشكلة تخزين التسلسل الهرمي الكامل للعرض لكل حالة في Perfetto لكل إطار. يمكن أن يؤدي تسجيل نافذة واحدة ، مثل NexusLauncher، إلى إنشاء أكثر من 30 ثانية من بيانات ViewCapture في ذاكرة تخزين مؤقت بسعة 10 ميغابايت. ومع ذلك، فإنّ التقاط أكثر من 30 نافذة من واجهة مستخدم النظام يتطلب إما ذاكرة تخزين مؤقت أكبر أو وقت تسجيل أقصر بكثير.

التعليمات

اتّبِع التعليمات التالية لإعداد ميزة ViewCapture في تطبيقات النظام:

  1. أضِف التبعية إلى ملف Android.bp، كما هو موضّح في رمز مشغّل التطبيقات.

    android_library {
        name: "YourLib",
        static_libs: [
              ...
            "//frameworks/libs/systemui:view_capture",
              ...
        ],
        platform_apis: true,
        privileged: true,
    }
    
  2. أنشئ مثيل ViewCapture عند إنشاء نافذتك، على سبيل المثال:

    • المثال 1:

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

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (enableViewCaptureTracing()) {
            mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
              .startCapture(getRootView(), ".NotificationShadeWindowView");
        }
        ...
      }
      
  3. أغلِق مثيل ViewCapture عند إغلاق النافذة، كما هو موضّح في المثالين التاليين:

    • المثال 1:

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

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