เพิ่มประสิทธิภาพอัตราเฟรมด้วยอัตราการรีเฟรชแบบปรับอัตโนมัติ

เมื่อเริ่มภาพเคลื่อนไหวใน Android จอแสดงผลมักจะเพิ่มอัตราการรีเฟรชสูงสุดเพื่อให้ใช้งานได้อย่างราบรื่น สำหรับภาพเคลื่อนไหวขนาดเล็ก เช่น แถบความคืบหน้าและโปรแกรมแสดงภาพเสียง อัตราการรีเฟรชสูงนี้ไม่จำเป็นและส่งผลให้ใช้พลังงานสูง

ตั้งแต่ Android 15 เป็นต้นไป อุปกรณ์ที่เปิดใช้ฟีเจอร์อัตราการรีเฟรชที่ปรับได้ (ARR) จะลดเวลาในการเข้าพักของอัตราการรีเฟรชสูงได้ 2 ด้าน ดังนี้

  • การเพิ่มประสิทธิภาพการจัดการอัตราเฟรมของแพลตฟอร์มใหม่ช่วยให้แอปแสดงผลด้วยอัตราเฟรมที่ต่ำลงโดยค่าเริ่มต้น และจะเพิ่มเป็นอัตราเฟรมสูงก็ต่อเมื่อจำเป็นเท่านั้น
  • อัตราการรีเฟรชจอแสดงผลจะปรับให้เข้ากับอัตราการแสดงผลเนื้อหาแบบไดนามิกโดยไม่กระตุก

แม้ว่าแอปส่วนใหญ่ควรได้รับประโยชน์จาก ARR โดยไม่ต้องมีการปรับแต่งใดๆ แต่คุณก็ลบล้างลักษณะการทำงานของอัตราเฟรมเริ่มต้นได้ตามต้องการ

หน้านี้จะอธิบายข้อมูลต่อไปนี้

  • วิธีกำหนดอัตราเฟรมของมุมมองแต่ละรายการ
  • นโยบายทั่วไปสำหรับวิธีที่ ARR กำหนดอัตราเฟรม
  • วิธีลบล้างลักษณะการทำงานของอัตราเฟรมเริ่มต้นด้วยตนเอง

กลไกการลงคะแนนเสียงของฟีเจอร์ดู

ในระบบ View ของ Android แต่ละ View ในลําดับชั้น UI สามารถแสดงอัตราเฟรมที่ต้องการได้ ระบบจะรวบรวมค่ากําหนดเหล่านี้และรวมเข้าด้วยกันเพื่อกําหนดอัตราเฟรมสุดท้ายสําหรับแต่ละเฟรม ซึ่งทำได้ผ่านกลไกการลงคะแนนเสียง โดยแต่ละมุมมองจะลงคะแนนตามแอตทริบิวต์อัตราเฟรม ซึ่งอาจเป็นหมวดหมู่หรืออัตราที่เฉพาะเจาะจง โดยปกติแล้ว ยอดดูจะเพิ่มขึ้นเมื่อมีการวาดหรืออัปเดต ระบบจะรวมการลงคะแนนเหล่านี้เข้าด้วยกันเพื่อกำหนดอัตราเฟรมสุดท้าย จากนั้นจะส่งไปยังเลเยอร์ระดับล่างเป็นคำแนะนำสำหรับการเรนเดอร์

ปัจจุบันฟีเจอร์ดูส่วนใหญ่จะใช้อัตราเฟรม "ปกติ" โดยค่าเริ่มต้น ซึ่งมักจะตั้งค่าไว้ที่ 60 Hz หากต้องการอัตราเฟรมที่สูงขึ้น คุณสามารถใช้ API ที่เฉพาะเจาะจงเพื่อปรับแต่งค่ากำหนดได้ โดยปกติแล้วระบบจะเลือกอัตราเฟรมที่สูงที่สุด ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ API เหล่านี้ได้ที่ส่วนตั้งค่าอัตราหรือหมวดหมู่เฟรม นโยบายทั่วไปเกี่ยวกับอัตราเฟรมอธิบายไว้ในส่วนนโยบาย ARR ทั่วไป

หมวดหมู่อัตราเฟรม

ในคลาส View มีหมวดหมู่อัตราเฟรมต่างๆ ที่ใช้โหวตได้ คำอธิบายของแต่ละหมวดหมู่มีดังนี้

  • REQUESTED_FRAME_RATE_CATEGORY_DEFAULT: ตั้งค่านี้เพื่อกลับไปใช้ลักษณะการทํางานเริ่มต้น ซึ่งบ่งบอกว่ามุมมองนี้ไม่มีข้อมูลอัตราเฟรม
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE: มุมมองจะไม่ส่งผลต่ออัตราเฟรม ซึ่งหมายความว่าแม้ว่ามุมมองจะใช้งานอยู่ แต่เฟรมเวิร์กจะไม่พิจารณามุมมองนั้นเมื่อกําหนดอัตราเฟรม
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL: บ่งบอกถึงอัตราเฟรมระดับกลางที่เหมาะสำหรับภาพเคลื่อนไหวที่ไม่ต้องใช้อัตราเฟรมที่สูงขึ้นหรือไม่ได้ประโยชน์จากความลื่นไหลสูง ซึ่งปกติจะอยู่ที่ 60 Hz หรือใกล้เคียง
  • REQUESTED_FRAME_RATE_CATEGORY_HIGH: ระบุอัตราเฟรมที่เหมาะสำหรับภาพเคลื่อนไหวที่ต้องใช้อัตราเฟรมสูง ซึ่งอาจเพิ่มความลื่นไหล แต่ก็อาจเพิ่มการใช้พลังงานด้วย

การลงคะแนนสำหรับมุมมองจะดำเนินการก็ต่อเมื่อต้องมีการวาดใหม่เท่านั้น อัตราเฟรมสุดท้ายจะกำหนดโดยคะแนนสูงสุด เช่น หากทุกเสียงโหวตเป็น "ปกติ" ระบบจะเลือก "ปกติ" เมื่อมีการโหวตทั้ง "ปกติ" และ "สูง" ระบบจะเลือก "สูง"

อัตราเฟรม

นอกจากหมวดหมู่อัตราเฟรมแล้ว ฟีเจอร์ดูยังระบุอัตราเฟรมที่ต้องการได้ด้วย เช่น 30, 60 หรือ 120 Hz เมื่อมีการโหวตอัตราเฟรมหลายรายการ อัตราเฟรมสุดท้ายจะกำหนดตามกฎต่อไปนี้

  • เป็นจำนวนที่คูณกันได้: หากอัตราเฟรมที่ผู้ใช้โหวตเป็นจำนวนที่คูณกันได้ ระบบจะเลือกค่าที่สูงที่สุด เช่น หากมี 2 เสียงโหวต ได้แก่ 30 Hz และ 90 Hz ระบบจะเลือก 90 Hz เป็นอัตราเฟรมสุดท้าย
  • ไม่ใช่จำนวนที่คูณกัน
    • หากคะแนนใดสูงกว่า 60 เฮิรตซ์ ระบบจะนับเป็นคะแนน "สูง"
    • หากคะแนนทั้งหมดคือ 60 Hz หรือต่ำกว่า ระบบจะนับเป็นคะแนน "ปกติ"

นอกจากนี้ หากมีทั้งค่าอัตราเฟรมและหมวดหมู่อัตราเฟรมรวมกัน ค่าที่สูงกว่ามักจะกำหนดอัตราการแสดงผลสุดท้าย เช่น หากใช้การโหวต 60 Hz ร่วมกับการโหวต "สูง" หรือใช้การโหวต 120 Hz ร่วมกับการโหวต "ปกติ" ระบบมักจะตั้งค่าอัตราการแสดงผลเป็น 120 Hz

นอกจากคะแนนโหวตจากแอปแล้ว อาจมีคำแนะนำอื่นๆ ที่ส่งไปยังเลเยอร์ระดับล่างจากคอมโพเนนต์ต่างๆ ภายในเฟรมเดียวกันด้วย ปัญหาเหล่านี้จำนวนมากอาจเกิดจากคอมโพเนนต์ UI ของระบบ เช่น หน้าต่างแจ้งเตือน แถบสถานะ แถบนําทาง และอื่นๆ ระบบจะกำหนดค่าอัตราเฟรมสุดท้ายตามคะแนนโหวตจากองค์ประกอบหลายรายการ

ตั้งค่าอัตราเฟรมหรือหมวดหมู่

ในบางกรณี คุณอาจมีอัตราเฟรมที่ต้องการสำหรับมุมมอง เช่น คุณสามารถตั้งค่าอัตราเฟรมที่ต้องการเป็น "สูง" สำหรับมุมมองเพื่อเพิ่มอัตราเฟรมหากภาพเคลื่อนไหวดูไม่ราบรื่น นอกจากนี้ หากมีภาพเคลื่อนไหวที่ช้าหรือนิ่งในวิดีโอ (โดยปกติจะเล่นที่ 24 หรือ 30 Hz) คุณอาจต้องการให้ภาพเคลื่อนไหวทำงานที่อัตราต่ำกว่า "ปกติ" เพื่อลดการใช้พลังงาน

คุณสามารถใช้ 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 ทั่วไป

ในส่วนก่อนหน้านี้ เราได้พูดถึงว่าภาพเคลื่อนไหวส่วนใหญ่จะแสดงที่ 60 ชม./วินาทีโดยค่าเริ่มต้น เนื่องจากแต่ละมุมมองตั้งค่าอัตราเฟรมที่ต้องการเป็น "ปกติ" อย่างไรก็ตาม มีข้อยกเว้นที่ระบบจะเพิ่มอัตราเฟรมเป็น "สูง" เพื่อให้ภาพเคลื่อนไหวลื่นไหลยิ่งขึ้น

นโยบาย 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()

การปรับปรุงการเลื่อน

Use Case หลักอย่างหนึ่งในการเพิ่มประสิทธิภาพอัตราเฟรมแบบไดนามิกคือการปรับปรุงประสบการณ์การเลื่อน (Fling) แอปพลิเคชันจำนวนมากอาศัยการปัดขึ้นของผู้ใช้เพื่อดูเนื้อหาใหม่ การเพิ่มประสิทธิภาพการเลื่อนของ ARR จะปรับอัตราการรีเฟรชแบบไดนามิกเมื่อท่าทางสัมผัสด้วยการปัดช้าลง โดยจะค่อยๆ ลดอัตราเฟรมลง ซึ่งจะช่วยให้การแสดงผลมีประสิทธิภาพมากขึ้นโดยยังคงการเลื่อนที่ราบรื่น

การปรับปรุงนี้มีผลเฉพาะกับคอมโพเนนต์ UI ที่เลื่อนได้ ซึ่งรวมถึง ScrollView, ListView และ GridView และอาจไม่พร้อมใช้งานสำหรับการใช้งานที่กําหนดเองบางรายการ

ฟีเจอร์การเลื่อน ARR พร้อมใช้งานสำหรับ 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 โดยค่าเริ่มต้นเพื่อเพิ่มประสิทธิภาพการใช้พลังงาน แม้ว่าคุณจะปิดใช้ฟีเจอร์นี้ได้ แต่เราไม่แนะนำให้ทำเนื่องจากแอปจะใช้พลังงานมากขึ้น โปรดพิจารณาปิดใช้ฟีเจอร์นี้เฉพาะในกรณีที่พบปัญหาที่ส่งผลต่อประสบการณ์ของผู้ใช้อย่างมาก

หากต้องการเปิดหรือปิดใช้ ARR ให้ใช้ setFrameRatePowerSavingsBalanced() API ใน Window หรือใช้ isFrameRatePowerSavingsBalanced() API ผ่านไฟล์ 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>