نرخ فریم را با نرخ تازه سازی تطبیقی ​​بهینه کنید

هنگامی که یک انیمیشن در اندروید شروع می شود، نمایشگر اغلب به حداکثر نرخ تازه سازی افزایش می یابد تا تجربه ای روان را تضمین کند. برای انیمیشن های کوچک مانند نوارهای پیشرفت و تصویرسازهای صوتی، این نرخ تازه سازی بالا غیر ضروری است و منجر به مصرف انرژی بالا می شود.

با شروع اندروید 15، با ویژگی نرخ تازه سازی تطبیقی ​​(ARR)، دستگاه های فعال می توانند اقامت با نرخ تازه سازی بالا را از دو جهت کاهش دهند:

  • با بهینه‌سازی‌های جدید مدیریت نرخ فریم پلتفرم، برنامه‌ها می‌توانند به‌طور پیش‌فرض با نرخ فریم پایین‌تری رندر شوند و تنها در صورت لزوم به نرخ فریم بالا افزایش دهند.
  • نرخ رفرش نمایشگر به صورت پویا با نرخ رندر محتوا بدون jank مطابقت دارد.

در حالی که اکثر برنامه‌ها باید بدون هیچ تغییری از ARR بهره ببرند، می‌توانید رفتار نرخ فریم پیش‌فرض را نیز در صورت نیاز لغو کنید.

این صفحه موارد زیر را شرح می دهد:

  • نرخ فریم هر View چگونه تعیین می شود.
  • خط مشی کلی برای اینکه چگونه ARR تعیین می کند نرخ فریم روی چه مقدار تنظیم شده است.
  • چگونه می توانید به صورت دستی رفتار نرخ فریم پیش فرض را لغو کنید.

مکانیسم رأی گیری View

در سیستم View Android، هر View در سلسله مراتب UI می تواند نرخ فریم ترجیحی خود را بیان کند. این تنظیمات برای تعیین نرخ فریم نهایی برای هر فریم جمع آوری و ترکیب می شوند. این امر از طریق مکانیزم رای گیری به دست می آید که در آن هر View بر اساس ویژگی نرخ فریم خود رای می دهد، که می تواند یک دسته یا یک نرخ خاص باشد. بازدیدها معمولاً هنگام ترسیم یا به‌روزرسانی رأی می‌دهند. این آرا برای تعیین نرخ فریم نهایی ترکیب می شوند، که سپس به عنوان راهنمایی برای رندر به لایه سطح پایین ارسال می شود.

در حال حاضر، اکثر بازدیدها به طور پیش‌فرض روی نرخ فریم «عادی» هستند که اغلب روی 60 هرتز تنظیم می‌شود. برای نرخ فریم بالاتر، می‌توانید از APIهای خاص برای سفارشی‌سازی تنظیمات برگزیده استفاده کنید، و سیستم معمولاً بالاترین نرخ فریم را انتخاب می‌کند. برای اطلاعات بیشتر در مورد استفاده از این APIها، به بخش تنظیم نرخ فریم یا دسته مراجعه کنید. سیاست های کلی پیرامون نرخ فریم در بخش سیاست عمومی ARR توضیح داده شده است.

دسته بندی نرخ فریم

در کلاس View دسته بندی های نرخ فریم مختلفی وجود دارد که می توان از آنها در رای گیری استفاده کرد. توضیحات هر دسته به شرح زیر است:

  • REQUESTED_FRAME_RATE_CATEGORY_DEFAULT : این مقدار را می توان برای بازگشت به رفتار پیش فرض تنظیم کرد، که نشان می دهد این View هیچ داده ای برای نرخ فریم ندارد.
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE : نما به صراحت بر نرخ فریم تأثیر نمی گذارد. این بدان معناست که حتی اگر View فعال باشد، فریمورک آن را هنگام تعیین نرخ فریم در نظر نخواهد گرفت
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL : نرخ فریم متوسطی را نشان می‌دهد که برای انیمیشن‌هایی مناسب است که به نرخ فریم بالاتری نیاز ندارند یا از صافی بالا بهره نمی‌برند. این معمولاً 60 هرتز یا نزدیک به آن است.
  • REQUESTED_FRAME_RATE_CATEGORY_HIGH : نرخ فریم مناسب برای انیمیشن هایی که به نرخ فریم بالایی نیاز دارند را نشان می دهد، که ممکن است نرمی را افزایش دهد اما ممکن است مصرف انرژی را نیز افزایش دهد.

یک View فقط در صورتی رای می دهد که نیاز به ترسیم مجدد داشته باشد. نرخ فریم نهایی با بالاترین رای تعیین می شود. به عنوان مثال، اگر همه آرا برای "عادی" باشد، "عادی" انتخاب می شود. هنگامی که هر دو رای "عادی" و "بالا" رخ می دهد، "بالا" انتخاب می شود.

نرخ فریم

علاوه بر دسته‌های نرخ فریم، یک View می‌تواند نرخ فریم ترجیحی مانند 30، 60 یا 120 هرتز را نیز تعیین کند. هنگامی که چندین رای نرخ فریم داده می شود، نرخ فریم نهایی با قوانین زیر تعیین می شود:

  • ضریب های یکدیگر : اگر نرخ فریم های رای داده شده مضرب یکدیگر باشند، بالاترین مقدار انتخاب می شود. به عنوان مثال، اگر دو رای وجود دارد - 30 هرتز و 90 هرتز - 90 هرتز به عنوان نرخ فریم نهایی انتخاب می شود.
  • مضرب یکدیگر نیستند :
    • اگر هر یک از آرا بیشتر از 60 هرتز باشد، به عنوان رای "بالا" محسوب می شود.
    • اگر همه آرا 60 هرتز یا کمتر باشد، به عنوان رای "عادی" محسوب می شود.

علاوه بر این، اگر ترکیبی از مقادیر نرخ فریم و دسته‌های نرخ فریم وجود داشته باشد، مقدار بالاتر معمولاً نرخ رندر نهایی را تعیین می‌کند. برای مثال، با ترکیبی از رای 60 هرتز و رای "بالا" یا رای 120 هرتز و رای "نرمال"، نرخ رندر معمولاً روی 120 هرتز تنظیم می شود.

علاوه بر آرای یک برنامه، ممکن است نکات دیگری نیز از اجزای مختلف در همان قاب به لایه سطح پایین ارسال شود. بسیاری از اینها می توانند از اجزای سیستم UI، مانند سایه اعلان، نوار وضعیت، نوار ناوبری و موارد دیگر منشأ بگیرند. مقادیر نهایی نرخ فریم بر اساس رای از چندین مؤلفه تعیین می شود.

نرخ فریم یا دسته را تنظیم کنید

تحت شرایط خاص، ممکن است نرخ فریم ترجیحی برای View داشته باشید. به عنوان مثال، می‌توانید نرخ فریم ترجیحی را برای نمایش روی «بالا» تنظیم کنید تا اگر انیمیشنی غیرصاف به نظر برسد، نرخ فریم را افزایش دهید. علاوه بر این، اگر یک انیمیشن آهسته یا ثابت روی یک ویدیو وجود دارد (معمولاً با فرکانس 24 یا 30 هرتز پخش می شود)، ممکن است ترجیح دهید انیمیشن با نرخی کمتر از «عادی» اجرا شود تا مصرف انرژی کاهش یابد.

می‌توانید از APIهای setRequestedFrameRate() و getRequestedFrameRate() برای تعیین نرخ فریم ترجیحی یا دسته بندی یک View خاص استفاده کنید.

کاتلین

// Set the preferred frame rate category to a View

// set the frame rate category to NORMAL
view.requestedFrameRate = View.REQUESTED_FRAME_RATE_CATEGORY_NORMAL
// set the frame rate category to HIGH
view.requestedFrameRate = View.REQUESTED_FRAME_RATE_CATEGORY_HIGH
// reset the frame rate category
view.requestedFrameRate = View.REQUESTED_FRAME_RATE_CATEGORY_DEFAULT

// Set the preferred frame rate to a View

// set the frame rate to 30
view.requestedFrameRate = 30f
// set the frame rate to 60
view.requestedFrameRate = 60f
// set the frame rate to 120
view.requestedFrameRate = 120f

جاوا

// Set the preferred frame rate category to a View

// set the frame rate category to NORMAL
view.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_NORMAL);
// set the frame rate category to HIGH
view.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_HIGH);
// reset the frame rate category
view.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_DEFAULT);

// Set the preferred frame rate to a View

// set the frame rate to 30
view.setRequestedFrameRate(30);
// set the frame rate to 60
view.setRequestedFrameRate(60);
// set the frame rate to 120
view.setRequestedFrameRate(120);

برای مثال استفاده، TextureView ببینید.

خط مشی عمومی ARR

در بخش قبل، بحث کردیم که اکثر انیمیشن ها به طور پیش فرض با فرکانس 60 هرتز نمایش داده می شوند، زیرا هر View دارای "Normal" به عنوان نرخ فریم ترجیحی است. با این حال، استثنائاتی وجود دارد که در آن نرخ فریم به «بالا» افزایش می‌یابد تا از انیمیشن‌های روان‌تر اطمینان حاصل شود.

سیاست کلی ARR به شرح زیر است:

  • تقویت لمسی : هنگامی که یک رویداد لمسی ( MotionEvent.ACTION_DOWN ) شناسایی می‌شود، برای حفظ پاسخ‌دهی، نرخ تازه‌سازی برای مدتی پس از انتشار لمس به «بالا» افزایش می‌یابد.
  • حرکات پرت کردن : با حرکات پرت کردن متفاوت رفتار می شود - با کاهش سرعت پرت کردن، نرخ تجدید به تدریج کاهش می یابد. می توانید جزئیات این رفتار را در بخش بهبود اسکرول پیدا کنید.
  • راه‌اندازی برنامه و انتقال پنجره : نرخ تازه‌سازی نیز برای مدتی در حین راه‌اندازی برنامه، مقداردهی اولیه پنجره، و انتقال پنجره افزایش می‌یابد تا از تجربه بصری روان اطمینان حاصل شود.
  • انیمیشن‌ها : انیمیشن‌هایی که شامل تغییر حرکت یا اندازه هستند، به‌طور خودکار نرخ تازه‌سازی بالاتری را دریافت می‌کنند تا وقتی موقعیت یا اندازه یک View تغییر می‌کند، صافی بیشتر شود.
  • SurfaceView و TextureView : نرخ‌های فریم که به صراحت برای TextureView و SurfaceView تنظیم شده‌اند رعایت می‌شوند و بر این اساس اعمال می‌شوند.

فعال و غیرفعال کردن افزایش لمس

می‌توانید تقویت لمسی را در سطح Window فعال و/یا غیرفعال کنید. به‌طور پیش‌فرض، وقتی کاربر انگشت خود را از روی صفحه لمس می‌کند و از روی صفحه بلند می‌کند، نرخ رندر برای مدتی افزایش می‌یابد. APIهای setFrameRateBoostOnTouchEnabled() و getFrameRateBoostOnTouchEnabled() به شما این امکان را می دهند که از افزایش نرخ رندر هنگام لمس یک Window خاص جلوگیری کنید.

کاتلین

// disable touch boost on a Window
window.isFrameRateBoostOnTouchEnabled = false 
// enable touch boost on a Window
window.isFrameRateBoostOnTouchEnabled = true
// check if touch boost is enabled on a Window
val isTouchBoostEnabled = window.isFrameRateBoostOnTouchEnabled

جاوا

// disable touch boost on a Window
window.setFrameRateBoostOnTouchEnabled(false)
// enable touch boost on a Window
window.setFrameRateBoostOnTouchEnabled(true)
// check if touch boost is enabled on a Window
window.getFrameRateBoostOnTouchEnabled()

بهبود اسکرول

یکی از موارد استفاده کلیدی برای بهینه سازی نرخ فریم به صورت پویا، بهبود تجربه اسکرول (پرت کردن) است. بسیاری از برنامه‌ها به شدت به کاربرانی وابسته هستند که برای مشاهده محتوای جدید، انگشت خود را به سمت بالا بکشند. بهبود پیمایش ARR به صورت پویا نرخ به‌روزرسانی را با کاهش سرعت حرکت حرکتی تنظیم می‌کند و به تدریج نرخ فریم را کاهش می‌دهد. این رندر کارآمدتر را در عین حفظ اسکرول صاف ارائه می دهد.

این بهبود به طور خاص برای اجزای رابط کاربری قابل پیمایش، از جمله ScrollView ، ListView ، و GridView اعمال می‌شود و ممکن است برای همه پیاده‌سازی‌های سفارشی در دسترس نباشد.

ویژگی پیمایش ARR برای RecyclerView و NestedScrollView در دسترس است. برای فعال کردن این ویژگی در برنامه خود، به آخرین نسخه AndroidX.recyclerview و AndroidX.core ارتقا دهید. برای جزئیات به جدول زیر مراجعه کنید.

کتابخانه

نسخه

AndroidX.recyclerview

1.4.0

AndroidX.core

1.15.0

اطلاعات سرعت را تنظیم کنید

اگر یک کامپوننت قابل پیمایش سفارشی دارید و می‌خواهید از ویژگی پیمایش استفاده کنید، در حالی که پیمایش یا پرت کردن نرم است، setFrameContentVelocity() روی هر فریم فراخوانی کنید. برای نمونه به قطعه کد زیر مراجعه کنید:

کاتلین

// set the velocity to a View (1000 pixels/Second)
view.frameContentVelocity = 1000f
// get the velocity of a View
val velocity = view.frameContentVelocity

جاوا

// set the velocity to a View
view.setFrameContentVelocity(velocity);

// get the velocity of a View
final float velocity = view.getFrameContentVelocity()

برای مثال‌های بیشتر، RecyclerView و ScrollView ببینید. برای تنظیم صحیح سرعت، اگر اطلاعات مورد نیاز را نمی‌توان از Scroller یا OverScroller دریافت کرد، سرعت محتوا (پیکسل در ثانیه) را به صورت دستی محاسبه کنید.

توجه داشته باشید که اگر setFrameContentVelocity() و getFrameContentVelocity() در View هایی که اجزای قابل پیمایش نیستند فراخوانی شوند، هیچ تاثیری نخواهند داشت، زیرا حرکت به طور خودکار باعث افزایش نرخ فریم بر اساس خط مشی فعلی می شود.

اطلاعات سرعت برای تنظیم نرخ رندر بسیار مهم است. به عنوان مثال، ژست پرت کردن را در نظر بگیرید. در ابتدا، سرعت پرتاب می‌تواند زیاد باشد و برای اطمینان از صاف بودن، به نرخ رندر بالاتری نیاز دارد. با پیشروی ژست، سرعت کاهش می‌یابد و امکان کاهش نرخ رندر را فراهم می‌کند.

ARR را فعال و غیرفعال کنید

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

برای فعال یا غیرفعال کردن ARR، از API setFrameRatePowerSavingsBalanced() در یک Window استفاده کنید یا از API isFrameRatePowerSavingsBalanced() از طریق فایل styles.xml خود استفاده کنید.

قطعه زیر نحوه فعال یا غیرفعال کردن ARR را در یک Window نشان می دهد:

کاتلین

// disable ARR on a Window
window.isFrameRatePowerSavingsBalanced = false 
// enable ARR on a Window
window.isFrameRatePowerSavingsBalanced = true  
// check if ARR is enabled on a Window
val isAdaptiveRefreshRateEnabled = window.isFrameRatePowerSavingsBalanced

جاوا

// disable ARR on a Window
window.setFrameRatePowerSavingsBalanced(false)
// enable ARR on a Window
window.setFrameRatePowerSavingsBalanced(true)
// check if ARR is enabled on a Window
window.isFrameRatePowerSavingsBalanced()

برای غیرفعال کردن ARR از طریق فایل styles.xml ، مورد زیر را به استایل خود در res/values/styles.xml اضافه کنید:

<style name="frameRatePowerSavingsBalancedDisabled">
    <item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
</style>