כשאנימציה מופעלת ב-Android, לרוב המסך מגיע לתדירות הרענון המקסימלית כדי להבטיח חוויה חלקה. באנימציות קטנות כמו סרגל התקדמות ותוכנות להצגת אודיו, אין צורך בקצב רענון גבוה, והוא גורם לצריכת אנרגיה גבוהה.
החל מגרסה 15 של Android, בעזרת התכונה 'קצב רענון מותאם' (ARR), במכשירים שתומכים בה אפשר לצמצם את משך הזמן שבו המסך פועל בקצב רענון גבוה בשני מישורים:
- בעזרת אופטימיזציות חדשות לניהול קצב הפריימים בפלטפורמה, אפליקציות יכולות לבצע רינדור בקצב פריימים נמוך יותר כברירת מחדל, ולהגביר את קצב הפריימים רק במקרים שבהם יש צורך בכך.
- קצב הרענון של המסך תואם באופן דינמי לקצב העיבוד של התוכן, ללא השהיה.
רוב האפליקציות אמורות ליהנות מ-ARR בלי שינויים, אבל אפשר גם לשנות את התנהגות ברירת המחדל של קצב הפריימים לפי הצורך.
בדף הזה מתוארים הנושאים הבאים:
- איך נקבע קצב הפריימים של כל צפייה.
- המדיניות הכללית שקובעת איך ARR קובע את קצב הפריימים.
- איך אפשר לשנות באופן ידני את התנהגות ברירת המחדל של קצב הפריימים.
מנגנון ההצבעה 'צפייה'
במערכת התצוגה של Android, כל View בהיררכיית ממשק המשתמש יכול להביע את קצב הפריימים המועדף עליו. ההעדפות האלה נאספות ומשולבות כדי לקבוע את קצב הפריימים הסופי של כל פריים. המערכת משתמשת במנגנון הצבעה שבו כל צפייה מצביעה על סמך מאפיין קצב הפריימים שלה, שיכול להיות קטגוריה או קצב ספציפי. בדרך כלל, הצופים מביעים את דעתם כשהם צופים בתוכן או כשהתוכן מתעדכן. ההצבעות האלה משולבות כדי לקבוע את קצב הפריימים הסופי, שנשלח לאחר מכן לשכבה ברמה נמוכה יותר בתור רמז לעיבוד.
נכון לעכשיו, ברירת המחדל של רוב התצוגות היא קצב פריימים 'רגיל', שלרוב מוגדר ל-60Hz. כדי להגדיר קצב פריימים גבוה יותר, אפשר להשתמש בממשקי API ספציפיים כדי להתאים אישית את ההעדפות. בדרך כלל, המערכת בוחרת את קצב הפריימים הגבוה ביותר. מידע נוסף על השימוש ב-API האלה זמין בקטע הגדרת קצב התמונות או הקטגוריה. המדיניות הכללית בנושא קצב הפריימים מתוארת בקטע המדיניות הכללית בנושא שיעור הצגת מודעות.
קטגוריות של קצב פריימים
בכיתה View
יש קטגוריות שונות של קצב פריימים שאפשר להשתמש בהן בסקרים. אלה התיאורים של כל קטגוריה:
REQUESTED_FRAME_RATE_CATEGORY_DEFAULT
: אפשר להגדיר את הערך הזה כדי לחזור להתנהגות ברירת המחדל, שמציינת שלתצוגה הזו אין נתונים לגבי קצב הפריימים.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE
: התצוגה לא תשפיע באופן מפורש על קצב הפריימים. כלומר, גם אם התצוגה פעילה, המסגרת לא תתייחס אליה כשתקבע את קצב הפריימים.REQUESTED_FRAME_RATE_CATEGORY_NORMAL
: קצב פריימים באמצע, שמתאים לאנימציות שלא דורשות קצב פריימים גבוה יותר או שלא נהנות מתנועה חלקה במיוחד. בדרך כלל היא 60Hz או קרובה לכך.REQUESTED_FRAME_RATE_CATEGORY_HIGH
: מציין קצב פריימים שמתאים לאנימציות שדורשות קצב פריימים גבוה. קצב הפריימים הזה עשוי לשפר את רמת החלקות, אבל גם להגדיל את צריכת החשמל.
המערכת תצביע על תצוגה רק אם צריך לצייר אותה מחדש. קצב הפריימים הסופי נקבע לפי ההצבעה הגבוהה ביותר. לדוגמה, אם כל ההצבעות הן על 'רגיל', האפשרות 'רגיל' תיבחר. אם מתקבלים הן 'רגילה' והן 'גבוהה', המערכת בוחרת באפשרות 'גבוהה'.
קצב פריימים
בנוסף לקטגוריות של קצב פריימים, אפשר לציין ב-View גם קצב פריימים מועדף, כמו 30, 60 או 120Hz. כשמתקבלים מספר קולות לגבי קצב הפריימים, קצב הפריימים הסופי נקבע לפי הכללים הבאים:
- כפולות של זוויות אחרות: אם שיעורי הפריימים שנבחרו הם כפולות של זוויות אחרות, המערכת בוחרת את הערך הגבוה ביותר. לדוגמה, אם יש שני דיווחים – 30 הרץ ו-90 הרץ – 90 הרץ נבחר כקצב הפריימים הסופי.
- לא מכפילים זה של זה:
- אם אחד מהצבעות הוא גבוה מ-60Hz, הוא נספר כ'גבוה'.
- אם כל הקולות הם 60Hz או פחות, הם נספרים כקולות 'רגילים'.
בנוסף, אם יש שילוב של ערכים של קצב פריימים וקטגוריות של קצב פריימים, בדרך כלל הערך הגבוה יותר קובע את קצב הרינדור הסופי. לדוגמה, בשילוב של הצבעה על 60Hz והצבעה על 'מהיר', או הצבעה על 120Hz והצבעה על 'רגיל', קצב הרינדור יוגדר בדרך כלל ל-120Hz.
בנוסף להצבעות מאפליקציה, יכול להיות שיהיו גם רמזים אחרים שנשלחים לשכבה ברמה נמוכה יותר מרכיבים שונים באותו פריים. רבים מהם יכולים לנבוע מרכיבים של ממשק המשתמש של המערכת, כמו חלונית ההתראות, שורת הסטטוס, סרגל הניווט ועוד. הערכים הסופיים של קצב הפריימים נקבעים על סמך ההצבעות מכמה רכיבים.
הגדרת קצב הפריימים או הקטגוריה
בנסיבות מסוימות, יכול להיות שתהיה לכם העדפה לקצב פריימים מסוים בתצוגה. לדוגמה, אפשר להגדיר את קצב הפריימים המועדף ל'גבוה' בתצוגה כדי להגדיל את קצב הפריימים אם האנימציה לא חלקה. בנוסף, אם יש אנימציה איטית או סטטית מעל סרטון (בדרך כלל מופעלת ב-24 או ב-30Hz), מומלץ להפעיל את האנימציה בקצב נמוך יותר מ'רגיל' כדי לצמצם את צריכת החשמל.
אפשר להשתמש בממשקי ה-API setRequestedFrameRate()
ו-getRequestedFrameRate()
כדי לציין את קצב הפריימים או את הקטגוריה המועדפים של תצוגה נתונה.
Kotlin
// 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
Java
// 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
בקטע הקודם, ציינו שרוב האנימציות מוצגות ב-60Hz כברירת מחדל, כי בכל תצוגה מוגדר 'רגיל' כקצב הפריימים המועדף. עם זאת, יש מקרים חריגים שבהם קצב הפריימים מוגדל ל'גבוה' כדי להבטיח אנימציות חלקות יותר.
המדיניות הכללית בנושא ARR היא:
- שיפור המגע: כשמתגלה אירוע מגע (
MotionEvent.ACTION_DOWN
), קצב הרענון מוגבר למצב 'מהיר' למשך זמן מה אחרי שהמגע משתחרר, כדי לשמור על תגובה מהירה. - תנועות משיכה: המערכת מטפלת בתנועות משיכה בצורה שונה – קצב הרענון יורד בהדרגה ככל שמהירות המשיכה פוחתת. פרטים על ההתנהגות הזו מופיעים בקטע שיפור גלילה.
- הפעלת אפליקציות ומעברים בין חלונות: קצב הרענון מואץ גם למשך זמן מה במהלך הפעלת אפליקציות, איפוס חלונות ומעברים בין חלונות, כדי להבטיח חוויה חזותית חלקה.
- אנימציות: אנימציות שכוללות תנועה או שינויים בגודל מקבלות באופן אוטומטי קצב רענון גבוה יותר כדי לשפר את רמת החלקות כשהמיקום או הגודל של תצוגה משתנים.
SurfaceView
ו-TextureView
: קצבי הפריימים שהוגדרו באופן מפורש ל-TextureView
ול-SurfaceView
יחולו בהתאם.
הפעלה והשבתה של שיפור המגע
אפשר להפעיל או להשבית את התכונה 'שיפור המגע' ברמה Window
. כברירת מחדל, כשמשתמש נוגע במסך ומרים את האצבע, קצב הרינדור עולה למשך זמן מה. ממשקי ה-API setFrameRateBoostOnTouchEnabled()
ו-getFrameRateBoostOnTouchEnabled()
מאפשרים למנוע עלייה בשיעור הרינדור כשמקישים על Window
ספציפי.
Kotlin
// 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
Java
// 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()
שיפור הגלילה
אחד מהתרחישים העיקריים לאופטימיזציה דינמית של קצב הפריימים הוא לשיפור חוויית הגלילה (fling). אפליקציות רבות מסתמכות במידה רבה על כך שהמשתמשים מחליקים למעלה כדי להציג תוכן חדש. כשמשתמשים בשיפור הגלילה של ARR, קצב הרענון משתנה באופן דינמי ככל שתנועת הזריקה מאטה, והוא יורד בהדרגה. כך מתבצע עיבוד יעיל יותר תוך שמירה על גלילה חלקה.
השיפור הזה רלוונטי במיוחד לרכיבי ממשק משתמש שאפשר לגלול בהם, כולל ScrollView
, ListView
ו-GridView
. יכול להיות שהוא לא יהיה זמין בכל הטמעות בהתאמה אישית.
התכונה של גלילה ב-ARR זמינה ב-RecyclerView
וב-NestedScrollView
. כדי להפעיל את התכונה הזו באפליקציה, צריך לשדרג לגרסאות האחרונות של AndroidX.recyclerview
ו-AndroidX.core
. פרטים נוספים מופיעים בטבלה הבאה.
ספרייה |
גרסה |
|
1.4.0 |
|
1.15.0 |
הגדרת פרטי המהירות
אם יש לכם רכיב מותאם אישית שאפשר לגלול בו ואתם רוצים לנצל את התכונה של הגלילה, צריך להפעיל את setFrameContentVelocity()
בכל פריים בזמן הגלילה החלקה או השליפה. קטע הקוד הבא הוא דוגמה לכך:
Kotlin
// set the velocity to a View (1000 pixels/Second) view.frameContentVelocity = 1000f // get the velocity of a View val velocity = view.frameContentVelocity
Java
// 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()
נקראים בתצוגות שאינן רכיבים שאפשר לגלול בהם, לא תהיה להם השפעה, כי תנועה מפעילה באופן אוטומטי עלייה בשיעור הפריימים בהתאם למדיניות הנוכחית.
נתוני המהירות חיוניים לשינוי קצב הרינדור. לדוגמה, אפשר להשתמש בתנועת השלכה. בהתחלה, המהירות של התנועה יכולה להיות גבוהה, ולכן צריך קצב רינדור גבוה יותר כדי להבטיח שהתנועה תהיה חלקה. ככל שהתנועה מתקדמת, המהירות יורדת, וכך ניתן להקטין את קצב הרינדור.
הפעלה והשבתה של ARR
ARR מופעל כברירת מחדל כדי לשפר את יעילות האנרגיה. אפשר להשבית את התכונה הזו, אבל לא מומלץ לעשות זאת כי האפליקציה תצרוך יותר חשמל. כדאי להשבית את התכונה הזו רק אם נתקלת בבעיות שמשפיעות באופן משמעותי על חוויית המשתמש.
כדי להפעיל או להשבית את ARR, משתמשים ב-API של setFrameRatePowerSavingsBalanced()
ב-Window
, או ב-API של isFrameRatePowerSavingsBalanced()
דרך הקובץ styles.xml
.
קטע הקוד הבא מראה איך מפעילים או משביתים את ARR ב-Window
:
Kotlin
// 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
Java
// 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>