تسمح واجهة برمجة التطبيقات لعدد اللقطات في الثانية للتطبيقات بإعلام نظام Android الأساسي بالإطار المقصود. يتوفّر في التطبيقات التي تستهدف الإصدار 11 من نظام التشغيل Android (المستوى 30 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث. في السابق، كانت معظم الأجهزة تتيح معدّل تحديث شاشة واحدًا فقط، وهو 60 هرتز عادةً، ولكن بدأ هذا الوضع يتغيّر. تتوافق العديد من الأجهزة الآن مع معدلات التحديث مثل 90 هرتز أو 120 هرتز تتيح بعض الأجهزة التبديل السلس بين معدّلات التحديث، بينما تعرض الأجهزة الأخرى شاشة سوداء لفترة قصيرة تبلغ عادةً ثانية واحدة.
إن الغرض الأساسي من واجهة برمجة التطبيقات هو تمكين التطبيقات من الاستفادة بشكل أفضل من جميع
معدلات تحديث الشاشة المتوافقة. على سبيل المثال، قد يؤدي تطبيق يشغّل فيديو بمعدّل 24 هرتز ويطلب setFrameRate()
إلى تغيير معدّل إعادة رسوم الشاشة من 60 هرتز إلى 120 هرتز. يتيح معدل التحديث الجديد هذا تشغيل فيديوهات بمعدل 24 هرتز بسلاسة وبصورة طبيعية، بدون الحاجة إلى استخدام ميزة "الترجيع/التسريع بنسبة 3 إلى 2" كما هو مطلوب لتشغيل الفيديو نفسه على شاشة بمعدل 60 هرتز. ويؤدي ذلك إلى تحسين تجربته.
الاستخدام الأساسي
يقدّم Android عدة طرق للوصول إلى مساحات العرض والتحكّم فيها، لذا تتوفّر
عدة إصدارات من واجهة برمجة التطبيقات setFrameRate()
. يأخذ كل إصدار من واجهة برمجة التطبيقات
المعلمات نفسها وتعمل بنفس طريقة عمل المعلَمات الأخرى:
Surface.setFrameRate()
SurfaceControl.Transaction.setFrameRate()
ANativeWindow_setFrameRate()
ASurfaceTransaction_setFrameRate()
لا يحتاج التطبيق إلى مراعاة معدّلات تحديث الشاشة الفعلية المتوافقة،
التي يمكن الحصول عليها من خلال الاتصال بـ
Display.getSupportedModes()
،
لطلب setFrameRate()
بأمان. على سبيل المثال، حتى إذا كان الجهاز
يتوافق مع 60 هرتز، ويمكنك الاتصال بـ setFrameRate()
مع ذِكر عدد اللقطات في الثانية الذي يفضّله تطبيقك.
أما الأجهزة التي لا تتطابق مع معدّل عرض اللقطات في التطبيق، فستعمل على
معدّل تحديث الشاشة الحالي.
لمعرفة ما إذا كان الاتصال برقم setFrameRate()
يؤدي إلى تغيير في معدّل إعادة رسوم الشاشة، يمكنك الاشتراك في خدمة تلقّي إشعارات تغييرات الشاشة من خلال الاتصال برقم
DisplayManager.registerDisplayListener()
أو AChoreographer_registerRefreshRateCallback()
.
عند استدعاء setFrameRate()
، من الأفضل ضبط معدل عرض اللقطات بالضبط بدلاً من تقريب القيمة إلى عدد صحيح. على سبيل المثال، عند عرض فيديو تم تسجيله في
29.97 هرتز، يمكنك اجتياز 29.97 بدلاً من التقريب إلى 30.
بالنسبة إلى تطبيقات الفيديو، يجب ضبط معلَمة التوافق التي تم ضبطها على setFrameRate()
.
إلى Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
لمنح تلميح إضافي
نظام Android الأساسي الذي سيستخدمه التطبيق القائمة المنسدلة للتكيف مع نظام Android الأساسي
معدّل تحديث الشاشة (مما سيؤدي إلى حدوث اهتزاز).
في بعض السيناريوهات، سيتوقف عرض الفيديو عن إرسال الإطارات، ولكنه سيبقى معروضًا.
على الشاشة لبعض الوقت. وتشمل السيناريوهات الشائعة الحالات التي يصل فيها تشغيل الفيديو
إلى نهايته أو عندما يوقف المستخدم تشغيل الفيديو مؤقتًا. في هذه الحالات،
طلب setFrameRate()
مع ضبط معلَمة عدد اللقطات في الثانية على 0 لمحو مساحة العرض
إعادة ضبط عدد اللقطات في الثانية على القيمة التلقائية ليس من الضروري محو إعداد معدل عرض اللقطات بهذه الطريقة عند إتلاف السطح أو عند إخفاء السطح لأنّ المستخدم ينتقل إلى تطبيق مختلف. لا تُمحو إعدادات معدل عرض اللقطات إلا عندما يظل السطح مرئيًا بدون استخدامه.
التبديل غير السلس لعدد اللقطات في الثانية
في بعض الأجهزة، قد يؤدي تبديل معدل التحديث إلى حدوث انقطاعات مرئية، مثل ظهور شاشة رمادية لعدة ثوانٍ. ويحدث ذلك عادةً على أجهزة الاستقبال الرقمية ولوحات التلفزيون
والأجهزة المشابهة. لا يبدّل إطار عمل Android الأوضاع تلقائيًا
عند طلب بيانات من واجهة برمجة التطبيقات Surface.setFrameRate()
لتجنُّب هذه الانقطاعات المرئية.
يفضّل بعض المستخدمين المقاطع المرئية في بداية ونهاية الفيديوهات الأطول. يتيح هذا الإجراء مطابقة معدّل تحديث الشاشة. عدد اللقطات في الثانية للفيديو، وتجنَّب عناصر تحويل عدد اللقطات في الثانية، مثل 3:2. وأداة الاهتزاز المنسدلة لتشغيل الفيلم.
ولهذا السبب، يمكن تفعيل مفاتيح تبديل معدل التحديث غير السلس إذا كانت موافقة المستخدمين والتطبيقات:
- المستخدمون: للتفعيل، يمكن للمستخدمين تفعيل عدد اللقطات في الثانية للمحتوى المطابق. الإعداد.
- التطبيقات: لتفعيل الميزة، يمكن للتطبيقات اجتياز
CHANGE_FRAME_RATE_ALWAYS
إلىsetFrameRate()
.
ننصحك دائمًا باستخدام CHANGE_FRAME_RATE_ALWAYS
للفيديوهات الطويلة مثل الأفلام. ويعود السبب في ذلك إلى أنّ ميزة مطابقة
عدد اللقطات في الثانية في الفيديو تفوق الانقطاع الذي يحدث عند تغيير
معدل التحديث.
اقتراحات إضافية
اتّبِع هذه الاقتراحات للسيناريوهات الشائعة.
مساحات عرض متعددة
تم تصميم نظام Android الأساسي للتعامل بشكل صحيح مع السيناريوهات التي تتضمّن سطحًا
متعدّدًا بإعدادات مختلفة لمعدل عرض اللقطات. عندما يتضمّن تطبيقك عدة سطحَين بمعدلات عرض لقطات مختلفة، يمكنك استدعاء setFrameRate()
مع معدل عرض اللقطة الصحيح لكل سطح. حتى إذا كان الجهاز يشغِّل تطبيقات متعددة في
باستخدام وضع "تقسيم الشاشة" أو وضع "نافذة ضمن النافذة"، يمكن لكل تطبيق إجراء مكالمة
setFrameRate()
لمساحات العرض الخاصة بهم.
لا يتغيّر النظام الأساسي لعدد اللقطات في الثانية للتطبيق
حتى إذا كان الجهاز متوافقًا مع عدد اللقطات في الثانية الذي يحدّده التطبيق في طلب
setFrameRate()
، في بعض الحالات لا يمكن للجهاز تبديل الشاشة إليها.
معدّل التحديث هذا على سبيل المثال، قد يكون لسطح العرض الأعلى أولوية إعداد مختلف
لمعدل عرض اللقطات، أو قد يكون الجهاز في وضع "توفير شحن البطارية" (يتم وضع
قيود على معدل تحديث الشاشة للحفاظ على شحن البطارية). يجب أن يظل التطبيق يعمل بشكلٍ سليم حتى إذا لم يبدِّل الجهاز معدّل تحديث الشاشة إلى إعداد معدّل عرض اللقطات في التطبيق، حتى إذا كان الجهاز يبدِّل الإعداد في الحالات العادية.
يُرجى العِلم أنّه على التطبيق تحديد كيفية الاستجابة عندما لا يتطابق معدل إعادة تحميل الشاشة
مع معدل عرض اللقطات في التطبيق. بالنسبة إلى الفيديو، يكون عدد اللقطات في الثانية ثابتًا مثل
الفيديو المصدر، ويجب استخدام شريط التمرير لعرض محتوى الفيديو. بدلاً من ذلك، قد تختار
اللعبة محاولة التشغيل بمعدّل تحديث الشاشة بدلاً من
الالتزام بمعدّل عرض اللقطات المفضّل لديها. يجب ألا يغيّر التطبيق القيمة التي يعرضها
يتم نقله إلى setFrameRate()
استنادًا إلى نشاط المنصة. يجب أن يبقى الجهاز مضبوطًا.
إلى عدد اللقطات في الثانية المفضَّل للتطبيق، بغض النظر عن طريقة تعامل التطبيق مع الحالات التي
عدم توافق المنصة مع طلب التطبيق. بهذه الطريقة، إذا تغيّرت
ظروف الجهاز للسماح باستخدام معدّلات إضافية لمعدل تحديث الشاشة، تحصل ال
منصّة على المعلومات الصحيحة للتبديل إلى معدل
اللقطات المفضّل للتطبيق.
في الحالات التي لا يعمل فيها التطبيق أو لا يمكنه العمل بمعدّل تحديث الشاشة، يجب أن يحدِّد التطبيق طوابع زمنية للعرض لكل إطار، باستخدام إحدى mekanismes منصّة لضبط الطوابع الزمنية للعرض:
يؤدي استخدام هذه الطوابع الزمنية إلى منع المنصة من عرض إطار التطبيق أيضًا. في وقت مبكر، مما قد يؤدي إلى إحداث اهتزاز غير ضروري. إنّ الاستخدام الصحيح للطابع الزمني لعرض اللقطات هو أمر صعب بعض الشيء. بالنسبة إلى الألعاب، يمكنك الاطّلاع على دليل معدل عرض اللقطات لمزيد من المعلومات حول تجنُّب الارتعاش، ويمكنك استخدام مكتبة معدل عرض اللقطات في Android.
في بعض الحالات، قد يبدّل النظام الأساسي إلى مضاعفات عدد اللقطات في الثانية الذي يستخدمه التطبيق.
المحددة في setFrameRate()
. على سبيل المثال، قد يتصل أحد التطبيقات بالرقم setFrameRate()
مع 60 هرتز وقد يبدّل الجهاز الشاشة إلى 120 هرتز. قد يعود سبب
حدوث ذلك إلى أنّ تطبيقًا آخر يتضمّن سطحًا تم ضبط معدل عرض اللقطات فيه على 24 هرتز. في
هذه الحالة، سيسمح تشغيل الشاشة بمعدّل 120 هرتز بتشغيل كلّ من سطح الشاشة بمعدّل 60 هرتز و
سطح الشاشة بمعدّل 24 هرتز بدون الحاجة إلى سحب الشاشة للأسفل.
عندما يتم عرض المحتوى بمعدّل مضاعَف لعدد اللقطات في الثانية للتطبيق، يجب أن يحدِّد التطبيق علامات زمنية للعرض لكل لقطة لتجنُّب الارتعاش غير الضروري. بالنسبة إلى الألعاب، تكون مكتبة "تنظيم سرعة اللقطات" في Android مفيدة لتحديد الطوابع الزمنية لعرض اللقطات بشكلٍ صحيح.
setFrameRate() مقابل preferredDisplayModeId
WindowManager.LayoutParams.preferredDisplayModeId
هي طريقة أخرى يمكن للتطبيقات من خلالها الإشارة إلى معدّل عرض اللقطات إلى المنصة. بعض الإشعارات
فقط في تغيير معدل تحديث الشاشة بدلاً من تغيير
إعدادات وضع العرض، مثل درجة دقة العرض. بشكل عام، استخدم
setFrameRate()
بدلاً من preferredDisplayModeId
إنّ استخدام الدالة setFrameRate()
أسهل لأنّ التطبيق لا يحتاج إلى البحث في قائمة modis of display للعثور على وضع يتضمّن معدّل عرض صور معيّنًا.
يمنح setFrameRate()
المنصة المزيد من الفرص لاختيار نموذج متوافق
عدد اللقطات في الثانية في السيناريوهات التي تكون فيها هناك مساحات عرض متعددة يتم تشغيلها
بمعدل عرض إطارات مختلف. على سبيل المثال، لنفترض أنّ تطبيقَين
يعملان في وضع "تقسيم الشاشة" على هاتف Pixel 4، حيث يشغّل أحدهما فيديو بمعدّل تكرار 24 هرتز
ويعرض الآخر للمستخدم قائمة قابلة للتنقّل. يتوافق هاتف Pixel 4 مع اثنين
معدلات تحديث الشاشة: 60 هرتز و90 هرتز. باستخدام واجهة برمجة التطبيقات preferredDisplayModeId
،
يتم إجبار مساحة عرض الفيديو على اختيار 60 هرتز أو 90 هرتز. من خلال الاتصال
setFrameRate()
مع 24 هرتز، يمنح سطح الفيديو المنصة مساحة أكبر
معلومات حول عدد اللقطات في الثانية للفيديو المصدر، ما يتيح للمنصة
اختَر 90 هرتز لمعدّل تحديث الشاشة، وهو أفضل من 60 هرتز في هذه الحالة.
السيناريو.
ومع ذلك، هناك سيناريوهات يجب فيها استخدام preferredDisplayModeId
بدلاً من setFrameRate()
، مثل ما يلي:
- إذا أراد التطبيق تغيير الدقة أو إعدادات وضع العرض الأخرى،
استخدِم
preferredDisplayModeId
. - لن تبدّل المنصة أوضاع العرض إلا استجابةً لطلب برمجي إلى
setFrameRate()
إذا كان تبديل الوضع خفيفًا ومن غير المرجّح أن يلاحظه المستخدم. إذا كان التطبيق يفضّل تبديل معدل إعادة التحديث للشاشة حتى إذا كان ذلك يتطلّب تبديل وضع كثيف (على سبيل المثال، على جهاز Android TV )، استخدِمpreferredDisplayModeId
. - يجب استخدام
preferredDisplayModeId
في التطبيقات التي لا يمكنها عرض المحتوى بمعدّل مضاعَف لمعدّل عرض اللقطات في التطبيق، ما يتطلّب ضبط الطوابع الزمنية للعرض على كل لقطة.
setFrameRate() مقابل preferredRefreshRate
WindowManager.LayoutParams#preferredRefreshRate
يضبط معدّل عرض اللقطات المفضّل في نافذة التطبيق، وينطبق المعدّل
على جميع مساحات العرض ضمن النافذة. يجب أن يحدّد التطبيق معدل التحديث المفضّل
بغض النظر عن معدّلات التحديث المتوافقة مع الجهاز، تمامًا كما هو الحال مع
setFrameRate()
، وذلك لتزويد أداة تحديد المهام بمعلومات أفضل عن معدل التحديث المقصود
للتطبيق.
يتم تجاهل preferredRefreshRate
على مساحات العرض التي تستخدم setFrameRate()
. بشكلٍ
عام، استخدِم setFrameRate()
إذا أمكن.
معدل التحديث المفضّل مقارنةً بمعرّف وضع العرض المفضّل
إذا كانت التطبيقات تريد تغيير معدل التحديث المفضّل فقط، يُفضّل استخدام
preferredRefreshRate
بدلاً من preferredDisplayModeId
.
تجنُّب استدعاء setFrameRate() بشكل متكرر جدًا
على الرغم من أنّ استدعاء setFrameRate()
ليس ذا تكلفة عالية من حيث الأداء،
يجب أن تتجنّب التطبيقات استدعاء setFrameRate()
في كل لقطة أو عدة مرات في
الثانية. من المرجح أن تؤدي المكالمات إلى setFrameRate()
إلى تغيير في
معدّل تحديث الشاشة، ما قد يؤدي إلى انخفاض عدد اللقطات في الثانية أثناء عملية الانتقال.
يجب تحديد معدّل عرض اللقطات الصحيح مسبقًا واستدعاء setFrameRate()
مرة واحدة.
استخدام الألعاب أو تطبيقات أخرى غير الفيديو
وعلى الرغم من أنّ الفيديو هو حالة الاستخدام الأساسية لواجهة برمجة تطبيقات setFrameRate()
، يمكن أن يكون
استخدامه للتطبيقات الأخرى. على سبيل المثال، اللعبة التي لا تهدف إلى تحقيق سعر أعلى من
بتردد 60 هرتز (لتقليل استخدام الطاقة والحصول على جلسات تشغيل أطول) يمكن الاتصال
Surface.setFrameRate(60, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT)
في هذه الدورة،
فإن الجهاز الذي يعمل بمعدل 90 هرتز بشكل افتراضي سيتم تشغيله بسرعة 60 هرتز، في حين أن
اللعبة نشطة، وهذا يؤدي إلى تجنب الاهتزاز الذي قد يحدث لولا ذلك في حالة
تشغيل اللعبة على 60 هرتز مع تشغيل الشاشة على 90 هرتز.
استخدام FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
"FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
" مخصّص لتطبيقات الفيديو فقط. بالنسبة
استخدام المحتوى بخلاف الفيديوهات، يُرجى استخدام FRAME_RATE_COMPATIBILITY_DEFAULT
.
اختيار استراتيجية لتغيير معدّل عرض اللقطات
- ننصحك بشدة بأن تستدعي التطبيقات
setFrameRate(
fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS)
عند عرض فيديوهات طويلة مثل الأفلام، حيث يشير fps إلى عدد اللقطات في الثانية للفيديو. - ننصحك بشدة بعدم السماح للتطبيقات باستدعاء
setFrameRate()
باستخدامCHANGE_FRAME_RATE_ALWAYS
عندما تتوقّع أن تستمر عملية تشغيل الفيديو لعدة دقائق أو أقل.
مثال على دمج تطبيقات تشغيل الفيديو
ننصحك باتّباع الخطوات التالية لدمج مفاتيح تبديل معدّل إعادة التحميل في التطبيقات التي تشغّل الفيديو:
- تحديد الخيار "
changeFrameRateStrategy
":- إذا كنت تشغّل فيديو طويلاً، مثل فيلم، استخدِم
MATCH_CONTENT_FRAMERATE_ALWAYS
. - في حال تشغيل فيديو قصير، مثل مقطع دعائي، استخدِم
CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS
.
- إذا كنت تشغّل فيديو طويلاً، مثل فيلم، استخدِم
- إذا كان الرمز
changeFrameRateStrategy
هوCHANGE_FRAME_RATE_ONLY_IF_SEAMLESS
، انتقِل إلى الخطوة 4. - اكتشاف ما إذا كان سيتم تبديل معدّل التحديث غير السلس أم لا من خلال التحقّق
أن كلتا هاتين المواتين صحيحتان:
- لا يمكن التبديل إلى الوضع السلس من معدّل التحديث الحالي (لنسميه "ج") إلى عدد اللقطات في الثانية للفيديو (لنسميه "و"). سيؤدي هذا إلى
هي الحالة إذا كان C وV مختلفين
Display.getMode().getAlternativeRefreshRates
لا يحتوي على مضاعف لـ V. - وافق المستخدم على إجراء تغييرات غير سلسة في معدّل إعادة التحميل. يمكنك اكتشاف
من خلال التحقّق ممّا إذا كان
DisplayManager.getMatchContentFrameRateUserPreference
إرجاعMATCH_CONTENT_FRAMERATE_ALWAYS
- لا يمكن التبديل إلى الوضع السلس من معدّل التحديث الحالي (لنسميه "ج") إلى عدد اللقطات في الثانية للفيديو (لنسميه "و"). سيؤدي هذا إلى
هي الحالة إذا كان C وV مختلفين
- لإجراء عملية التبديل بسلاسة، عليك اتّباع الخطوات التالية:
- الاتصال بالرقم
setFrameRate
وتمريرfps
،FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
، وchangeFrameRateStrategy
، حيث يشيرfps
إلى عدد اللقطات في الثانية للفيديو. - بدء تشغيل الفيديو
- الاتصال بالرقم
- إذا كان تغيير الوضع غير سلس على وشك الحدوث، عليك اتّباع الخطوات التالية:
- عرض تجربة المستخدم لإعلام المستخدم. يُرجى العلم أنّنا ننصحك بتوفير طريقة لسماح للمستخدم بإغلاق تجربة المستخدم هذه وتخطّي التأخير الإضافي في الخطوة 5.د. هذا هو لأن التأخير الذي ننصح به أكبر من اللازم على الشاشات التي تعرض أوقات تبديل أسرع.
- اتصل بـ
setFrameRate
وقدِّم لهfps
وFRAME_RATE_COMPATIBILITY_FIXED_SOURCE
وCHANGE_FRAME_RATE_ALWAYS
، حيث يكونfps
هو عدد اللقطات في الثانية للفيديو. - انتظِر معاودة الاتصال من
onDisplayChanged
. - انتظِر لمدة ثانيتين إلى أن تكتمل عملية تبديل الوضع.
- بدء تشغيل الفيديو
في ما يلي الرمز الزائف الذي يتيح استخدام التبديل السلس فقط:
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
transaction.setFrameRate(surfaceControl,
contentFrameRate,
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
transaction.apply();
beginPlayback();
في ما يلي الرمز الزائف الذي يمكن استخدامه لإتاحة التبديل السلس وغير السلس كما هو موضّح أعلاه:
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
if (isSeamlessSwitch(contentFrameRate)) {
transaction.setFrameRate(surfaceControl,
contentFrameRate,
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
transaction.apply();
beginPlayback();
} else if (displayManager.getMatchContentFrameRateUserPreference()
== MATCH_CONTENT_FRAMERATE_ALWAYS) {
showRefreshRateSwitchUI();
sleep(shortDelaySoUserSeesUi);
displayManager.registerDisplayListener(…);
transaction.setFrameRate(surfaceControl,
contentFrameRate,
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
CHANGE_FRAME_RATE_ALWAYS);
transaction.apply();
waitForOnDisplayChanged();
sleep(twoSeconds);
hideRefreshRateSwitchUI();
beginPlayback();
}