使用自動調整刷新率來改善影格速率

在 Android 中啟動動畫時,螢幕通常會提高至最高的螢幕刷新率,以確保流暢的使用體驗。對於進度列和音訊視覺化工具等小型動畫,這種高刷新率並非必要,反而會導致高耗電量。

自 Android 15 起,透過自動調整螢幕更新率 (ARR) 功能,啟用裝置可從兩方面降低高螢幕更新率停留時間:

  • 透過新的平台影格速率管理最佳化功能,應用程式預設以較低的畫面更新率算繪,並只在必要時提升至高畫面更新率。
  • 螢幕刷新率會動態配合內容算繪率,不會造成卡頓。

雖然大多數應用程式不必進行任何修改,即可享有 ARR 的好處,但您也可以視需要覆寫預設的幀率行為。

本頁面將說明以下內容:

  • 如何判斷每個 View 的影格速率。
  • 這項政策是 ARR 決定影格速率設定值的一般政策。
  • 如何手動覆寫預設影格速率行為。

View 投票機制

在 Android 的 View 系統中,UI 階層中的每個 View 都可以表示其偏好的影格速率。系統會收集並合併這些偏好設定,以決定每個影格的最終影格速率。這項功能是透過投票機制達成,每個 View 會根據其影格速率屬性 (可為類別或特定速率) 投票。檢視畫面通常會在繪製或更新時投票。系統會將這些投票結果加總,以決定最終的幀率,然後將其傳送至較低層級的圖層,做為算繪的提示。

目前,大多數 View 預設為「Normal」影格速率,通常會設為 60 Hz。如要使用更高的影格速率,您可以使用特定 API 自訂偏好設定,系統通常會選取最高的影格速率。如要進一步瞭解如何使用這些 API,請參閱「設定影格速率或類別」一節。如要瞭解關於影格速率的一般政策,請參閱「一般 ARR 政策」一節。

影格速率類別

View 類別中,有不同的影格速率類別可用於投票。各類別的說明如下:

View 只會在需要重新繪製時投票。最終的幀率會以最高票數決定。舉例來說,如果所有投票結果都是「正常」,系統就會選取「正常」。如果同時有「正常」和「高」的投票結果,系統會選擇「高」。

畫面更新率

除了影格速率類別之外,View 也可以指定偏好的影格速率,例如 30、60 或 120 Hz。如果投出多個影格速率票數,最終影格速率會根據下列規則決定:

  • 相乘:如果投票選出的影格速率是相乘的倍數,系統會選擇最高的值。舉例來說,如果有兩個投票結果 (30 Hz 和 90 Hz),系統會選取 90 Hz 做為最終的幀率。
  • 不重疊
    • 如果任何投票次數超過 60 次/秒,就會計為「高」票。
    • 如果所有投票次數都為 60 Hz 以下,則視為「正常」投票。

此外,如果影格速率值和影格速率類別同時存在,通常會以較高的值決定最終的顯示速率。舉例來說,如果同時收到 60 Hz 投票和「高」投票,或是 120 Hz 投票和「正常」投票,則算繪速率通常會設為 120 Hz。

除了應用程式提供的投票外,同一個影格內的不同元件,也可能會向較低層級的圖層傳送其他提示。其中許多元素可來自系統 UI 元件,例如通知遮罩、狀態列、導覽列等。最終的幀率值會根據多個元件的投票結果決定。

設定影格速率或類別

在某些情況下,您可以為 View 設定偏好的畫面更新率。舉例來說,如果動畫看起來不流暢,您可以將 View 的偏好影格速率設為「High」,以便提高影格速率。此外,如果影片中出現速度緩慢或靜態的動畫 (通常以 24 或 30 Hz 播放),建議您將動畫的播放速率設為低於「正常」的值,以減少耗電量。

您可以使用 setRequestedFrameRate()getRequestedFrameRate() API 指定特定 View 的偏好影格速率或類別。

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 Hz 的速度顯示,因為每個 View 都將「Normal」設為偏好的影格速率。不過,在某些例外情況下,系統會將影格速率提高至「高」,以確保動畫更流暢。

一般 ARR 政策如下:

  • 觸控加速:偵測到觸控事件 (MotionEvent.ACTION_DOWN) 後,系統會在觸控動作釋放後一段時間內將更新率提升至「高」,以維持回應速度。
  • 滑動手勢:滑動手勢的處理方式有所不同,隨著滑動速度減緩,更新率也會逐漸降低。如需這項行為的詳細資訊,請參閱「捲動功能改善」一節。
  • 應用程式啟動和視窗轉換:在應用程式啟動、視窗初始化和視窗轉換期間,系統也會提升更新率,以確保流暢的視覺體驗。
  • 動畫:涉及移動或大小變更的動畫會自動獲得更高的刷新率,以便在 View 位置或大小變更時,提升流暢度。
  • SurfaceViewTextureView:系統會根據 TextureViewSurfaceView 明確設定的畫面更新率,並據此套用。

啟用及停用觸控加速功能

您可以在 Window 層級啟用及/或停用觸控加速功能。根據預設,當使用者輕觸螢幕並將手指移開時,算繪速率會提升一段時間。setFrameRateBoostOnTouchEnabled()getFrameRateBoostOnTouchEnabled() API 可讓您在觸碰特定 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 捲動強化功能會動態調整重新整理率,逐漸降低影格速率。這可提供更有效率的算繪,同時維持流暢的捲動效果。

這項改善項目專門適用於可捲動的 UI 元件,包括 ScrollViewListViewGridView,且可能不適用於所有自訂實作。

RecyclerViewNestedScrollView 支援 ARR 捲動功能。如要在應用程式中啟用這項功能,請升級至 AndroidX.recyclerviewAndroidX.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()

如需更多範例,請參閱 RecyclerViewScrollView。如要正確設定速度,如果無法從 ScrollerOverScroller 取得必要資訊,請手動計算內容速度 (每秒像素)。

請注意,如果在非可捲動元件的 View 上呼叫 setFrameContentVelocity()getFrameContentVelocity(),則不會產生任何效果,因為移動會自動根據目前的政策觸發更高的影格速率。

速度資訊對於調整轉譯率至關重要。舉例來說,請考慮甩動手勢。一開始,甩動動作的速度可能會很高,因此需要更高的算繪速率來確保流暢度。隨著手勢動作的進行,速度會降低,讓算繪速率降低。

啟用及停用 ARR

ARR 預設為啟用,可提升電力效率。雖然您可以停用這項功能,但我們不建議這麼做,因為應用程式會耗用更多電力。只有在遇到嚴重影響使用者體驗的問題時,才考慮停用這項功能。

如要啟用或停用 ARR,請在 Window 上使用 setFrameRatePowerSavingsBalanced() API,或透過 styles.xml 檔案使用 isFrameRatePowerSavingsBalanced() API。

下列程式碼片段說明如何在 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 檔案停用 ARR,請在 res/values/styles.xml 的樣式中加入下列項目:

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