Uyarlanabilir yenileme oranıyla kare hızını optimize etme

Android'de bir animasyon başlatıldığında, sorunsuz bir deneyim sağlamak için ekran genellikle maksimum yenileme hızına yükselir. İlerleme çubukları ve ses görselleştiricileri gibi küçük animasyonlarda bu yüksek yenileme hızı gereksizdir ve yüksek güç tüketimine neden olur.

Android 15'ten itibaren, etkinleştirilen uyarlanabilir yenileme hızı (ARR) özelliği sayesinde cihazlar, yüksek yenileme hızı kullanımını iki açıdan azaltabilir:

  • Yeni platform kare hızı yönetimi optimizasyonları sayesinde uygulamalar varsayılan olarak daha düşük bir kare hızında oluşturulabilir ve yalnızca gerektiğinde yüksek kare hızına yükseltilebilir.
  • Ekran yenileme hızı, içerik oluşturma hızıyla dinamik olarak eşleşir ve takılma olmaz.

Çoğu uygulama, herhangi bir değişiklik yapılmadan ARR'den yararlanabilir. Ancak gerektiğinde varsayılan kare hızı davranışını da geçersiz kılabilirsiniz.

Bu sayfada aşağıdaki konular açıklanmaktadır:

  • Her bir görünümün kare hızı nasıl belirlenir?
  • ARR'nin kare hızının neye ayarlanacağını belirleme konusundaki genel politikası.
  • Varsayılan kare hızı davranışını manuel olarak nasıl geçersiz kılabilirsiniz?

The View oylama mekanizması

Android'in View sisteminde, kullanıcı arayüzü hiyerarşisindeki her View, tercih ettiği kare hızını ifade edebilir. Bu tercihler, her kare için nihai bir kare hızı belirlemek üzere toplanır ve birleştirilir. Bu, her bir görünümün kare hızı özelliğine göre oy kullandığı bir oylama mekanizmasıyla sağlanır. Kare hızı özelliği, bir kategori veya belirli bir hız olabilir. Görünümler genellikle çizildiğinde veya güncellendiğinde oylanır. Bu oylar, nihai kare hızını belirlemek için birleştirilir. Ardından, oluşturma ipucu olarak alt katmana gönderilir.

Şu anda çoğu görünümde varsayılan olarak "Normal" kare hızı kullanılır ve bu hız genellikle 60 Hz olarak ayarlanır. Daha yüksek kare hızları için tercihleri özelleştirmek üzere belirli API'leri kullanabilirsiniz. Sistem genellikle en yüksek kare hızını seçer. Bu API'leri kullanma hakkında daha fazla bilgi için Kare hızını veya kategoriyi ayarlama bölümüne bakın. Kare hızlarıyla ilgili genel politikalar Genel ARR politikası bölümünde açıklanmıştır.

Kare hızı kategorileri

View sınıfında, oylamada kullanılabilecek farklı kare hızı kategorileri vardır. Her kategorinin açıklaması aşağıdaki gibidir:

  • REQUESTED_FRAME_RATE_CATEGORY_DEFAULT: Bu değer, varsayılan davranışa dönmek için ayarlanabilir. Bu durumda, bu görünümün kare hızıyla ilgili verileri olmadığı belirtilir.
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE: Görünüm, kare hızını açıkça etkilemez. Bu, Görünüm etkin olsa bile çerçevenin kare hızını belirlerken bunu dikkate almayacağı anlamına gelir.
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL: Daha yüksek kare hızları gerektirmeyen veya yüksek akıcılıktan faydalanmayan animasyonlar için uygun olan orta kare hızını gösterir. Bu değer normalde 60 Hz veya buna yakın bir değerdir.
  • REQUESTED_FRAME_RATE_CATEGORY_HIGH: Yüksek kare hızı gerektiren animasyonlar için uygun bir kare hızını gösterir. Bu hız, akıcılığı artırabilir ancak güç kullanımını da artırabilir.

Görünüm yalnızca yeniden çizilmesi gerekiyorsa oylama yapar. Nihai kare hızı, en yüksek oya göre belirlenir. Örneğin, tüm oylar "Normal" içinse "Normal" seçilir. Hem "Normal" hem de "Yüksek" oy verildiğinde "Yüksek" seçilir.

Kare hızı

Görünüm, kare hızı kategorilerine ek olarak 30, 60 veya 120 Hz gibi tercih edilen bir kare hızı da belirtebilir. Birden fazla kare hızı oyu verildiğinde nihai kare hızı aşağıdaki kurallara göre belirlenir:

  • Birbirinin katı olanlar: Oylanan kare hızları birbirinin katıysa en yüksek değer seçilir. Örneğin, 30 Hz ve 90 Hz olmak üzere iki oy varsa nihai kare hızı olarak 90 Hz seçilir.
  • Birbirinin katı olmayanlar:
    • Oylardan herhangi biri 60 Hz'den yüksekse "Yüksek" oyu olarak sayılır.
    • Tüm oylar 60 Hz veya daha düşükse "Normal" oy olarak kabul edilir.

Ayrıca, hem kare hızı değerleri hem de kare hızı kategorileri bir arada bulunuyorsa genellikle daha yüksek değer, son oluşturma hızını belirler. Örneğin, 60 Hz oylama ile "Yüksek" oylama veya 120 Hz oylama ile "Normal" oylama kombinasyonunda, oluşturma hızı genellikle 120 Hz olarak ayarlanır.

Bir uygulamadan gelen oylara ek olarak, aynı çerçeve içindeki farklı bileşenlerden alt katmana gönderilen başka ipuçları da olabilir. Bunların çoğu, bildirim gölgesi, durum çubuğu ve gezinme çubuğu gibi Sistem Kullanıcı Arayüzü bileşenlerinden kaynaklanabilir. Son kare hızı değerleri, birden fazla bileşenin oylarına göre belirlenir.

Kare hızını veya kategoriyi ayarlama

Belirli durumlarda bir görünüm için tercih edilen kare hızınız olabilir. Örneğin, bir görünüm için tercih edilen kare hızını "Yüksek" olarak ayarlayarak animasyonun akıcı görünmemesi durumunda kare hızını artırabilirsiniz. Ayrıca, bir videonun üzerinde yavaş veya statik bir animasyon varsa (genellikle 24 ya da 30 Hz'de oynatılır) güç tüketimini azaltmak için animasyonun "Normal" hızdan daha düşük bir hızda çalışmasını tercih edebilirsiniz.

Belirli bir görünümün tercih edilen kare hızını veya kategorisini belirlemek için setRequestedFrameRate() ve getRequestedFrameRate() API'lerini kullanabilirsiniz.

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

Örnek kullanım için TextureView bölümüne bakın.

Genel ARR politikası

Önceki bölümde, her Görünüm'de tercih edilen kare hızı olarak "Normal" ayarlandığından çoğu animasyonun varsayılan olarak 60 Hz'de gösterildiğini ele almıştık. Ancak daha akıcı animasyonlar sağlamak için kare hızının "Yüksek" olarak ayarlandığı istisnai durumlar vardır.

Genel ARR politikası aşağıdaki gibidir:

  • Dokunma artırma: Bir dokunma etkinliği (MotionEvent.ACTION_DOWN) algılandığında, dokunma bırakıldıktan sonra bir süre boyunca yanıt verme hızını korumak için yenileme hızı "Yüksek" olarak artırılır.
  • Fırlatma hareketleri: Fırlatma hareketleri farklı şekilde işlenir. Fırlatma hızı yavaşladıkça yenileme hızı kademeli olarak düşer. Bu davranışla ilgili ayrıntıları Kaydırma iyileştirme bölümünde bulabilirsiniz.
  • Uygulama başlatma ve pencere geçişleri: Uygulama başlatma, pencere başlatma ve pencere geçişleri sırasında bir süre boyunca yenileme hızı da artırılır. Böylece, sorunsuz bir görsel deneyim sağlanır.
  • Animasyonlar: Hareket veya boyut değişiklikleri içeren animasyonlar, bir görünümün konumu ya da boyutu değiştiğinde akıcılığı artırmak için otomatik olarak daha yüksek bir yenileme oranı alır.
  • SurfaceView ve TextureView: TextureView ve SurfaceView için açıkça ayarlanan kare hızları dikkate alınır ve buna göre uygulanır.

Dokunarak hızlandırmayı etkinleştirme ve devre dışı bırakma

Dokunarak hızlandırma özelliğini Window düzeyinde etkinleştirebilir ve/veya devre dışı bırakabilirsiniz. Varsayılan olarak, kullanıcı parmağıyla ekrana dokunup parmağını kaldırdığında bir süre boyunca oluşturma hızı artar. setFrameRateBoostOnTouchEnabled() ve getFrameRateBoostOnTouchEnabled() API'leri, belirli bir Window öğesine dokunulduğunda oluşturma hızının artmasını engellemenize olanak tanır.

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

Kaydırma iyileştirmesi

Kare hızını dinamik olarak optimize etmenin temel kullanım alanlarından biri, kaydırma (fırlatma) deneyimini iyileştirmektir. Birçok uygulama, yeni içerikleri görüntülemek için kullanıcıların yukarı kaydırmasına büyük ölçüde bağlıdır. ARR kaydırma geliştirmesi, aktarma hareketi yavaşladıkça yenileme hızını dinamik olarak ayarlar ve kare hızını kademeli olarak düşürür. Bu sayede, sorunsuz kaydırma sağlanırken daha verimli bir oluşturma süreci elde edilir.

Bu iyileştirme özellikle ScrollView, ListView ve GridView gibi kaydırılabilir kullanıcı arayüzü bileşenleri için geçerlidir ve tüm özel uygulamalarda kullanılamayabilir.

ARR kaydırma özelliği RecyclerView ve NestedScrollView için kullanılabilir. Uygulamanızda bu özelliği etkinleştirmek için AndroidX.recyclerview ve AndroidX.core'nin en son sürümlerine yükseltin. Ayrıntılar için aşağıdaki tabloya bakın.

Kitaplık

Sürüm

AndroidX.recyclerview

1.4.0

AndroidX.core

1.15.0

Hız bilgilerini ayarlama

Özel bir kaydırılabilir bileşeniniz varsa ve kaydırma özelliğinden yararlanmak istiyorsanız sorunsuz kaydırma veya hızlı kaydırma sırasında her karede setFrameContentVelocity() işlevini çağırın. Örnek için aşağıdaki kod snippet'ine bakın:

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

Daha fazla örnek için RecyclerView ve ScrollView sayfalarına bakın. Hızı doğru şekilde ayarlamak için gerekli bilgiler Scroller veya OverScroller üzerinden alınamıyorsa içerik hızını (saniyede piksel) manuel olarak hesaplayın.

setFrameContentVelocity() ve getFrameContentVelocity(), kaydırılabilir olmayan bileşenlerde çağrılırsa hareket, geçerli politikaya göre kare hızını otomatik olarak artırdığından herhangi bir etkisi olmaz.

Hızı ayarlamak için hız bilgisi çok önemlidir. Örneğin, hızlıca kaydırma hareketini ele alalım. Başlangıçta, fırlatma hızı yüksek olabilir. Bu durumda, akıcılığı sağlamak için daha yüksek bir oluşturma hızı gerekir. Hareket ilerledikçe hız azalır ve oluşturma hızının düşürülmesine olanak tanır.

ARR'yi etkinleştirme ve devre dışı bırakma

ARR, güç verimliliğini artırmak için varsayılan olarak etkindir. Bu özelliği devre dışı bırakabilirsiniz ancak uygulamanın daha fazla güç tüketeceği için bu işlem önerilmez. Bu özelliği yalnızca kullanıcı deneyimini önemli ölçüde etkileyen sorunlarla karşılaşırsanız devre dışı bırakmayı düşünün.

ARR'yi etkinleştirmek veya devre dışı bırakmak için Window üzerinde setFrameRatePowerSavingsBalanced() API'sini ya da styles.xml dosyanız üzerinden isFrameRatePowerSavingsBalanced() API'sini kullanın.

Aşağıdaki snippet'te, Window üzerinde ARR'nin nasıl etkinleştirileceği veya devre dışı bırakılacağı gösterilmektedir:

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'yi styles.xml dosyası üzerinden devre dışı bırakmak için res/values/styles.xml içindeki stilinize aşağıdaki öğeyi ekleyin:

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

Compose için ARR

Compose 1.9, uyarlanabilir yenileme oranı desteği de ekler. Görüntüleme sisteminde, bir Görüntüleme için belirli bir kare hızı istemek üzere setRequestedFrameRate() yöntemini kullanırsınız. Compose'da yeni bir değiştirici, composable'ın kare hızını belirtmenize olanak tanır. Bu değiştirici, setRequestedFrameRate() ile benzer şekilde çalışır ve pozitif bir kare hızı değeri (Hz cinsinden) veya önceden tanımlanmış bir kare hızı kategorisi olan FrameRateCategory değerini kabul eder.

API'lerin imzaları aşağıdaki gibidir:

Aşağıdaki snippet'te, yeni kare hızı değiştiricisi (Modifier.requestedFrameRate(120f)), bir Text composable'a uygulanır. Bu değiştirici, Text composable'ın çizilirken veya animasyon oluşturulurken (örneğin, opaklık değişiklikleriyle) 120 kare/saniye tercih edilen kare hızını istemesine neden olur:

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

Ardından, her bir composable'ın tercih edilen kare hızları toplanır ve her kare için nihai kare hızını belirlemek üzere birleştirilir. Daha fazla bilgi için SetFrameRateSample ve SetFrameRateCategorySample sayfalarına bakın.