अडैप्टिव रीफ़्रेश रेट की मदद से फ़्रेम रेट को ऑप्टिमाइज़ करना

का इस्तेमाल करें.

Android में ऐनिमेशन शुरू होने पर, डिसप्ले अक्सर ज़्यादा से ज़्यादा रीफ़्रेश रेट पर बूस्ट होता है, ताकि बेहतर अनुभव मिल सके. प्रोग्रेस बार और ऑडियो विज़ुअलाइज़र जैसे छोटे ऐनिमेशन के लिए, ज़्यादा रीफ़्रेश रेट की ज़रूरत नहीं होती. इससे बैटरी की खपत ज़्यादा होती है.

Android 15 में, अडैप्टिव रिफ़्रेश रेट (एआरआर) की सुविधा उपलब्ध है. इस सुविधा को चालू करने पर, डिवाइस इन दो तरीकों से ज़्यादा रिफ़्रेश रेट को कम कर सकते हैं:

  • प्लेटफ़ॉर्म के फ़्रेम रेट मैनेजमेंट से जुड़े नए ऑप्टिमाइज़ेशन की मदद से, ऐप्लिकेशन डिफ़ॉल्ट रूप से कम फ़्रेम रेट पर रेंडर हो सकते हैं. साथ ही, ज़रूरत पड़ने पर ही ज़्यादा फ़्रेम रेट पर रेंडर हो सकते हैं.
  • डिसप्ले की रीफ़्रेश दर, कॉन्टेंट रेंडर होने की दर से डाइनैमिक तरीके से मैच होती है. इसमें किसी तरह की रुकावट नहीं आती.

ज़्यादातर ऐप्लिकेशन को बिना किसी बदलाव के एआरआर से फ़ायदा मिलना चाहिए. हालांकि, ज़रूरत पड़ने पर फ़्रेम रेट के डिफ़ॉल्ट व्यवहार को भी बदला जा सकता है.

इस पेज पर, इनके बारे में बताया गया है:

  • हर व्यू का फ़्रेम रेट कैसे तय किया जाता है.
  • यह सामान्य नीति है. इससे यह तय होता है कि ARR, फ़्रेम रेट को किस वैल्यू पर सेट करेगा.
  • फ़्रेम रेट के डिफ़ॉल्ट तरीके को मैन्युअल तरीके से कैसे बदला जा सकता है.

वोटिंग की सुविधा देखने का तरीका

Android के व्यू सिस्टम में, यूज़र इंटरफ़ेस (यूआई) के हर व्यू में, अपने पसंदीदा फ़्रेम रेट को सेट करने का विकल्प होता है. इन प्राथमिकताओं को इकट्ठा किया जाता है और एक साथ मिलाकर, हर फ़्रेम के लिए फ़ाइनल फ़्रेम रेट तय किया जाता है. यह वोटिंग सिस्टम के ज़रिए किया जाता है. इसमें हर व्यू, फ़्रेम रेट एट्रिब्यूट के आधार पर वोट करता है. यह एट्रिब्यूट, कैटगरी या कोई खास रेट हो सकता है. आम तौर पर, व्यू को ड्रा किए जाने या अपडेट किए जाने पर वोट किया जाता है. इन वोटों को मिलाकर, फ़ाइनल फ़्रेम रेट तय किया जाता है. इसके बाद, इसे रेंडरिंग के लिए हिंट के तौर पर, लोअर-लेवल लेयर को भेजा जाता है.

फ़िलहाल, ज़्यादातर व्यू के लिए डिफ़ॉल्ट फ़्रेम रेट "सामान्य" होता है. इसे अक्सर 60 हर्ट्ज़ पर सेट किया जाता है. ज़्यादा फ़्रेम रेट के लिए, खास एपीआई का इस्तेमाल करके अपनी पसंद के मुताबिक सेटिंग की जा सकती हैं. हालांकि, सिस्टम आम तौर पर सबसे ज़्यादा फ़्रेम रेट चुनता है. इन एपीआई का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, फ़्रेम रेट या कैटगरी सेट करना सेक्शन देखें. फ़्रेम रेट से जुड़ी सामान्य नीतियों के बारे में, एआरआर से जुड़ी सामान्य नीति सेक्शन में बताया गया है.

फ़्रेम रेट की कैटगरी

View क्लास में, फ़्रेम रेट की अलग-अलग कैटगरी होती हैं. इनका इस्तेमाल वोटिंग में किया जा सकता है. हर कैटगरी के बारे में यहां बताया गया है:

  • REQUESTED_FRAME_RATE_CATEGORY_DEFAULT: इस वैल्यू को डिफ़ॉल्ट सेटिंग पर वापस लाने के लिए सेट किया जा सकता है. इससे पता चलता है कि इस व्यू में फ़्रेम रेट के लिए कोई डेटा नहीं है.
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE: व्यू से फ़्रेम रेट पर कोई असर नहीं पड़ेगा. इसका मतलब है कि व्यू चालू होने पर भी, फ़्रेमवर्क फ़्रेम रेट तय करते समय इस पर ध्यान नहीं देगा
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL: यह एक सामान्य फ़्रेम रेट है. यह ऐसे ऐनिमेशन के लिए सही है जिनके लिए ज़्यादा फ़्रेम रेट की ज़रूरत नहीं होती या जो ज़्यादा स्मूद नहीं होते. आम तौर पर, यह 60 हर्ट्ज़ या इसके आस-पास होता है.
  • REQUESTED_FRAME_RATE_CATEGORY_HIGH: इससे पता चलता है कि यह फ़्रेम रेट, ऐसे ऐनिमेशन के लिए सही है जिनके लिए ज़्यादा फ़्रेम रेट की ज़रूरत होती है. इससे ऐनिमेशन ज़्यादा स्मूद हो सकता है, लेकिन इससे बैटरी की खपत भी बढ़ सकती है.

व्यू सिर्फ़ तब वोट करता है, जब उसे फिर से ड्रॉ करने की ज़रूरत होती है. फ़ाइनल फ़्रेम रेट, सबसे ज़्यादा वोट के आधार पर तय किया जाता है. उदाहरण के लिए, अगर सभी वोट "सामान्य" के लिए हैं, तो "सामान्य" को चुना जाएगा. अगर "सामान्य" और "ज़्यादा" दोनों तरह के वोट मिलते हैं, तो "ज़्यादा" को चुना जाता है.

फ़्रेम दर

फ़्रेम रेट कैटगरी के अलावा, व्यू में पसंदीदा फ़्रेम रेट भी तय किया जा सकता है. जैसे, 30, 60 या 120 हर्ट्ज़. जब फ़्रेम रेट के लिए कई वोट डाले जाते हैं, तो फ़ाइनल फ़्रेम रेट इन नियमों के हिसाब से तय किया जाता है:

  • एक-दूसरे के गुणज: अगर वोट किए गए फ़्रेम रेट एक-दूसरे के गुणज हैं, तो सबसे ज़्यादा वैल्यू को चुना जाता है. उदाहरण के लिए, अगर दो वोट हैं - 30 हर्ट्ज़ और 90 हर्ट्ज़ — तो 90 हर्ट्ज़ को फ़ाइनल फ़्रेम रेट के तौर पर चुना जाता है.
  • एक-दूसरे के मल्टीपल नहीं होने चाहिए:
    • अगर किसी भी वोट की फ़्रीक्वेंसी 60 हर्ट्ज़ से ज़्यादा है, तो उसे "ज़्यादा" वोट माना जाता है.
    • अगर सभी वोट 60 हर्ट्ज़ या इससे कम हैं, तो इसे "सामान्य" वोट माना जाता है.

इसके अलावा, अगर फ़्रेम रेट की वैल्यू और फ़्रेम रेट कैटगरी, दोनों का कॉम्बिनेशन है, तो आम तौर पर ज़्यादा वैल्यू से फ़ाइनल रेंडर रेट तय होता है. उदाहरण के लिए, 60 हर्ट्ज़ और "ज़्यादा" या 120 हर्ट्ज़ और "सामान्य" के कॉम्बिनेशन के साथ, रेंडर रेट आम तौर पर 120 हर्ट्ज़ पर सेट होता है.

किसी ऐप्लिकेशन से मिले वोट के अलावा, एक ही फ़्रेम में मौजूद अलग-अलग कॉम्पोनेंट से भी लोअर-लेवल लेयर को अन्य सुझाव भेजे जा सकते हैं. इनमें से कई, सिस्टम यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट से जनरेट हो सकते हैं. जैसे, सूचना पैनल, स्टेटस बार, नेविगेशन बार वगैरह. फ़ाइनल फ़्रेम रेट वैल्यू, कई कॉम्पोनेंट के वोटों के आधार पर तय की जाती हैं.

फ़्रेम रेट या कैटगरी सेट करना

कुछ मामलों में, आपके पास किसी व्यू के लिए पसंदीदा फ़्रेम रेट चुनने का विकल्प होता है. उदाहरण के लिए, अगर कोई ऐनिमेशन ठीक से नहीं चल रहा है, तो व्यू के लिए पसंदीदा फ़्रेम रेट को "ज़्यादा" पर सेट किया जा सकता है, ताकि फ़्रेम रेट को बढ़ाया जा सके. इसके अलावा, अगर वीडियो पर धीरे-धीरे या स्थिर ऐनिमेशन (आम तौर पर 24 या 30 हर्ट्ज़ पर चलाया जाता है) दिखाया जा रहा है, तो हो सकता है कि आपको बैटरी की खपत कम करने के लिए, ऐनिमेशन को "सामान्य" से कम दर पर चलाने का विकल्प चुनना पड़े.

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 देखें.

एआरआर से जुड़ी सामान्य नीति

पिछले सेक्शन में, हमने बताया था कि ज़्यादातर ऐनिमेशन डिफ़ॉल्ट रूप से 60 हर्ट्ज़ पर दिखाए जाते हैं. ऐसा इसलिए होता है, क्योंकि हर व्यू के लिए पसंदीदा फ़्रेम रेट "Normal" पर सेट होता है. हालांकि, कुछ मामलों में फ़्रेम रेट को "ज़्यादा" पर सेट किया जाता है, ताकि ऐनिमेशन को ज़्यादा स्मूद बनाया जा सके.

एआरआर से जुड़ी सामान्य नीति यहां दी गई है:

  • टच बूस्ट: जब किसी टच इवेंट (MotionEvent.ACTION_DOWN) का पता चलता है, तो टच करने के बाद कुछ समय के लिए रीफ़्रेश रेट को "ज़्यादा" पर सेट कर दिया जाता है, ताकि स्क्रीन पर तुरंत प्रतिक्रिया मिल सके.
  • फ़्लिंग जेस्चर: फ़्लिंग जेस्चर को अलग तरीके से हैंडल किया जाता है. फ़्लिंग की स्पीड कम होने पर, रीफ़्रेश रेट धीरे-धीरे कम होता जाता है. इस व्यवहार के बारे में ज़्यादा जानकारी के लिए, स्क्रोलिंग को बेहतर बनाना सेक्शन देखें.
  • ऐप्लिकेशन लॉन्च करने और विंडो ट्रांज़िशन के दौरान: ऐप्लिकेशन लॉन्च करने, विंडो शुरू करने, और विंडो ट्रांज़िशन के दौरान, कुछ समय के लिए रीफ़्रेश रेट को भी बढ़ाया जाता है, ताकि विज़ुअल एक्सपीरियंस बेहतर हो.
  • ऐनिमेशन: जिन ऐनिमेशन में अपने-आप मूवमेंट होता है या साइज़ बदलता है उन्हें ज़्यादा रीफ़्रेश रेट मिलता है. इससे व्यू की पोज़िशन या साइज़ बदलने पर, ऐनिमेशन ज़्यादा आसानी से दिखता है.
  • SurfaceView और TextureView: TextureView और SurfaceView के लिए साफ़ तौर पर सेट किए गए फ़्रेम रेट का पालन किया जाता है और उन्हें उसी के मुताबिक लागू किया जाता है.

टच बूस्ट की सुविधा को चालू और बंद करना

Window लेवल पर, टच बूस्ट की सुविधा को चालू और/या बंद किया जा सकता है. डिफ़ॉल्ट रूप से, जब कोई उपयोगकर्ता स्क्रीन को छूता है और अपनी उंगली हटाता है, तो कुछ समय के लिए रेंडर रेट बढ़ जाता है. 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()

स्क्रोल करने की सुविधा में सुधार

फ़्रेम रेट को डाइनैमिक तरीके से ऑप्टिमाइज़ करने का एक मुख्य फ़ायदा यह है कि इससे स्क्रोलिंग (फ़्लिंग) का अनुभव बेहतर होता है. कई ऐप्लिकेशन में, नया कॉन्टेंट देखने के लिए उपयोगकर्ताओं को ऊपर की ओर स्वाइप करना पड़ता है. ARR स्क्रोलिंग की बेहतर सुविधा, फ़्लिंग जेस्चर की स्पीड कम होने पर रीफ़्रेश रेट को डाइनैमिक तरीके से अडजस्ट करती है. इससे फ़्रेम रेट धीरे-धीरे कम होता है. इससे रेंडरिंग ज़्यादा बेहतर तरीके से होती है और स्क्रोलिंग भी आसानी से होती है.

यह सुधार, स्क्रोल किए जा सकने वाले यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट पर लागू होता है. जैसे, ScrollView, ListView, और GridView. यह सभी कस्टम लागू करने के लिए उपलब्ध नहीं हो सकता.

एआरआर स्क्रोल करने की सुविधा, RecyclerView और NestedScrollView के लिए उपलब्ध है. अपने ऐप्लिकेशन में इस सुविधा को चालू करने के लिए, AndroidX.recyclerview और AndroidX.core के नए वर्शन पर अपग्रेड करें. ज़्यादा जानकारी के लिए, यहां दी गई टेबल देखें.

लाइब्रेरी

वर्शन

AndroidX.recyclerview

1.4.0

AndroidX.core

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 को चालू या बंद करने के लिए, Window पर setFrameRatePowerSavingsBalanced() एपीआई का इस्तेमाल करें या अपनी styles.xml फ़ाइल के ज़रिए isFrameRatePowerSavingsBalanced() एपीआई का इस्तेमाल करें.

नीचे दिए गए स्निपेट में, Window पर ARR की सुविधा चालू या बंद करने का तरीका बताया गया है:

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()

styles.xml फ़ाइल के ज़रिए एआरआर की सुविधा बंद करने के लिए, res/values/styles.xml में अपनी स्टाइल में यह आइटम जोड़ें:

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

Compose के लिए ARR

Compose 1.9 में अडैप्टिव रीफ़्रेश रेट की सुविधा भी जोड़ी गई है. व्यू सिस्टम में, setRequestedFrameRate() तरीके का इस्तेमाल करके, किसी व्यू के लिए खास फ़्रेम रेट का अनुरोध किया जाता है. Compose में, एक नए मॉडिफ़ायर की मदद से कंपोज़ेबल के लिए फ़्रेम रेंडर होने की दर तय की जा सकती है. यह मॉडिफ़ायर, setRequestedFrameRate() की तरह काम करता है. इसमें फ़्रेम रेट की पॉज़िटिव वैल्यू (हर्ट्ज़ में) या पहले से तय की गई फ़्रेम रेट कैटगरी, FrameRateCategory स्वीकार की जाती है.

एपीआई के सिग्नेचर यहां दिए गए हैं:

नीचे दिए गए स्निपेट में, फ़्रेम रेट मॉडिफ़ायर (Modifier.requestedFrameRate(120f)) को Text कंपोज़ेबल पर लागू किया गया है. इस मॉडिफ़ायर की वजह से, Text कंपोज़ेबल को रेंडर या ऐनिमेशन करते समय, 120 फ़्रेम प्रति सेकंड की पसंदीदा फ़्रेम रेट का अनुरोध करना पड़ता है. उदाहरण के लिए, ओपैसिटी में बदलाव के साथ:

var targetAlpha by remember { mutableFloatStateOf(1f) }
val alpha by
    animateFloatAsState(
        targetValue = targetAlpha,
        animationSpec = tween(durationMillis = 1000)
    )

Button(
    onClick = { targetAlpha = if (targetAlpha == 1f) 0.2f else 1f },
    modifier =
        Modifier.background(LocalContentColor.current.copy(alpha = alpha))
) {
    Text(
        text = "Click",
        color = LocalContentColor.current.copy(alpha = alpha),
        modifier = Modifier.preferredFrameRate(120f)
     // You can also pass frame rate category such as FrameRateCategory.High  to increase the frame rate
    )
  }

इसके बाद, सभी कंपोज़ेबल से पसंदीदा फ़्रेम रेट इकट्ठा किए जाते हैं और उन्हें एक साथ मिलाकर, हर फ़्रेम के लिए फ़ाइनल फ़्रेम रेट तय किया जाता है. ज़्यादा जानकारी के लिए, SetFrameRateSample और SetFrameRateCategorySample देखें.