Kare hızı API'si, uygulamaların Android platformunu amaçlanan kare hızları hakkında bilgilendirmesine olanak tanır ve Android 11 (API düzeyi 30) veya sonraki sürümleri hedefleyen uygulamalarda kullanılabilir. Önceden çoğu cihaz yalnızca tek bir ekran yenileme hızını destekliyordu. ancak bu değer değişti. Birçok cihaz artık 90 Hz veya 120 Hz gibi yenileme hızları. Bazı cihazlar yenileme hızı geçişlerini kesintisiz şekilde desteklerken bazıları genellikle bir saniye süren kısa bir süreliğine siyah ekran gösterir.
API'nin birincil amacı, uygulamaların tüm Android platformlarından daha iyi
desteklenen ekran yenileme hızlarını ayarlar. Örneğin, setFrameRate()
çağrısı yapan ve 24 Hz video oynatan bir uygulama, cihazın ekran yenileme hızını 60 Hz'den 120 Hz'ye değiştirmesine neden olabilir. Bu yeni yenileme hızı, 24 Hz videonun 60 Hz ekranda oynatılması için gereken 3:2 kaydırma işlemine gerek kalmadan sorunsuz ve takılma olmadan oynatılmasını sağlar. Bu, daha iyi bir kullanıcı deneyimi sağlar.
Temel kullanım
Android, yüzeylere erişmek ve bunları kontrol etmek için çeşitli yöntemler sunar. Bu nedenle, setFrameRate()
API'nin birkaç sürümü vardır. API'nin her sürümü
ve diğerleriyle aynı şekilde çalışır:
Surface.setFrameRate()
SurfaceControl.Transaction.setFrameRate()
ANativeWindow_setFrameRate()
ASurfaceTransaction_setFrameRate()
Uygulamanın, setFrameRate()
'ı güvenli bir şekilde çağırmak için desteklenen gerçek ekran yenileme hızlarını dikkate alması gerekmez. Bu hızları Display.getSupportedModes()
çağrısı yaparak elde edebilirsiniz. Örneğin, cihaz yalnızca
60 Hz'i destekliyorsa setFrameRate()
uygulamasını uygulamanızın tercih ettiği kare hızıyla arayın.
Uygulamanın kare hızı için daha iyi bir eşleşmeye sahip olmayan cihazlar
yenileme hızına ayarlanır.
setFrameRate()
çağrısının ekran yenileme hızında bir değişikliğe yol açıp açmadığını görmek için DisplayManager.registerDisplayListener()
veya AChoreographer_registerRefreshRateCallback()
numaralı telefondan arayarak ekran değişikliği bildirimlerine kaydolun.
setFrameRate()
işlevini çağırırken, tam kare hızını bir tam sayıya yuvarlamak yerine tam olarak iletmek en iyisidir. Örneğin, 29,97 Hz'de kaydedilen bir videoyu oluştururken 30'a yuvarlamak yerine 29,97 değerini iletin.
Video uygulamaları için setFrameRate()
parametresine iletilen uyumluluk parametresi, Android platformuna uygulamanın eşleşmeyen bir ekran yenileme hızına uyum sağlamak için açılır menüyü kullanacağıyla ilgili ek bir ipucu vermek üzere Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
olarak ayarlanmalıdır (bu da titremeye neden olur).
Bazı senaryolarda video yüzeyi, kare göndermeyi durdurur ancak bu şekilde kalır.
ekranda bir süre görünür. Oynatma işleminin videonun sonuna ulaşması veya kullanıcının oynatmayı duraklatması gibi durumlar yaygın senaryolardır. Bu durumlarda, yüzeyin kare hızı ayarını varsayılan değere döndürmek için kare hızı parametresi 0 olarak ayarlanmış şekilde setFrameRate()
'ü çağırın. Kare hızı ayarı temizleniyor
Örneğin, yüzeyleri yok ederken veya yüzey düzlemi çalışırken
kullanıcı farklı bir uygulamaya geçtiği için gizlidir. Kare hızını temizle
yalnızca yüzey kullanılmadan görünür kaldığında ayarlanır.
Kesintisiz olmayan kare hızı anahtarı
Bazı cihazlarda, yenileme hızı geçişinde siyah gibi görsel kesintiler olabilir
bir iki saniyeliğine ekranda kalır. Bu durum genellikle set üstü kutularda, TV panellerinde ve benzer cihazlarda görülür. Android çerçevesi, bu tür görsel kesintileri önlemek için varsayılan olarak Surface.setFrameRate()
API'si çağrıldığında mod değiştirmez.
Bazı kullanıcılar başlangıçta görsel bir kesintiyi uzun videoların sonu gelir. Bu, ekranın yenileme hızının eşleşmesini sağlar Video kare hızını değiştirmeyin ve 3:2 gibi kare hızı dönüştürme eserlerinden kaçının. titremesini kullanabilirsiniz.
Bu nedenle, kesintisiz olmayan yenileme hızı anahtarları hem kullanıcı ve uygulama etkinleştirmesi:
- Kullanıcılar: Kullanıcılar, bu özelliği etkinleştirmek için İçerik kare hızını eşle kullanıcı ayarını etkinleştirebilir.
- Uygulamalar: Etkinleştirmek için uygulamalar
CHANGE_FRAME_RATE_ALWAYS
setFrameRate()
hedefine.
Her zaman CHANGE_FRAME_RATE_ALWAYS
kullanmanızı öneririz.
filmler gibi uzun süreli videolar için. Bunun nedeni, video kare hızını eşleştirmenin avantajının, yenileme hızını değiştirirken oluşan kesintinin ağır basmasıdır.
Ek öneriler
Sık karşılaşılan senaryolarda aşağıdaki önerileri uygulayın.
Birden fazla yüzey
Android platformu, mobil cihazlarda bir sürü
Farklı kare hızı ayarlarına sahip birden fazla yüzey Uygulamanızda birden fazla
farklı kare hızlarına sahip yüzeyler için setFrameRate()
çağırarak doğru
her yüzeyin kare hızını artırabilirsiniz. Cihaz bölünmüş ekran veya pencere içinde pencere modunu kullanarak birden fazla uygulamayı çalıştırsa bile her uygulama kendi yüzeyleri için setFrameRate()
'ü güvenli bir şekilde çağırabilir.
Platform, uygulamanın kare hızına göre değişmez.
Cihaz, uygulamanın bir çağrıda belirttiği kare hızını desteklese bile
setFrameRate()
, cihazın ekranı
yenileme hızında gösterilir. Örneğin, daha yüksek öncelikli bir yüzeyin farklı bir kare hızı ayarı olabilir veya cihaz pil tasarrufu modunda olabilir (pil tasarrufu için ekran yenileme hızında kısıtlama ayarlanır). Cihaz normal şartlarda ekran yenileme hızını uygulamanın kare hızı ayarına geçirse bile uygulama, cihaz ekran yenileme hızını uygulamanın kare hızı ayarına geçirmediğinde de düzgün şekilde çalışmaya devam etmelidir.
Ekran yenileme hızına ne zaman yanıt verileceğine uygulama karar verir.
uygulamanın kare hızıyla eşleşmiyor. Video için kare hızı, kaynak videonun kare hızına sabitlenir ve video içeriğini göstermek için açılır menü gerekir. CEVAP
Bunun yerine oyun, yerine ekranın yenileme hızında
tercih ettiği kare hızında kalmaya devam eder. Uygulama, değeri değiştirmemelidir.
platformun ne yaptığına bağlı olarak setFrameRate()
için geçilir. Ayarlanmış durumda kalmalıdır
uygulamanın tercih edilen kare hızına
platform, uygulamanın isteğiyle eşleşecek şekilde ayarlanmaz. Bu şekilde cihazın
ek ekran yenileme hızlarının kullanılmasına izin verecek şekilde değişirse,
platform, uygulamanın tercih edilen çerçevesine geçmek için doğru bilgilere sahip
oranıdır.
Uygulama, ekran yenileme hızında çalışmadığı veya çalışamadığı durumlarda, platformun sunum zaman damgalarını ayarlamak için kullandığı mekanizmalar:
Bu zaman damgalarını kullanmak, platformun uygulama çerçevesini çok erken sunmasını engeller. Bu da gereksiz sarsıntılara neden olur. Çerçeve sunma zaman damgalarının doğru kullanımı biraz karmaşıktır. Oyunlarda titremeden kaçınma hakkında daha fazla bilgi için kare hızı kılavuzumuza göz atın ve Android Frame Pacing kitaplığını kullanmayı düşünün.
Bazı durumlarda platform, uygulamanın kare hızının katlarından birine geçiş yapabilir
setFrameRate()
içinde belirtilir. Örneğin, bir uygulama setFrameRate()
çağırabilir
60 Hz'e çevirebilir ve cihaz ekranı 120 Hz'e geçirebilir. Bunun nedenlerinden biri,
başka bir uygulamanın yüzeyi 24 Hz kare hızı ayarına sahip olduğunda görülür. Bu durumda, ekranı 120 Hz'de çalıştırmak hem 60 Hz yüzeyin hem de 24 Hz yüzeyin, kaydırma gerekmeden çalışmasına olanak tanır.
Ekran, uygulamanın kare hızının bir katı hızda çalışırken uygulama, gereksiz titremeyi önlemek için her kare için sunma zaman damgalarını belirtmelidir. Oyunlarda Android Frame Pacing kitaplığını doğru çerçeve sunumu zaman damgalarını ayarlayabilirsiniz.
setFrameRate() ve preferredDisplayModeId
WindowManager.LayoutParams.preferredDisplayModeId
uygulamaların kare hızlarını platforma bildirmelerinin başka bir yoludur. Bazı uygulamalar, ekran çözünürlüğü gibi diğer ekran modu ayarlarını değiştirmek yerine yalnızca ekran yenileme hızını değiştirmek ister. Genel olarak,
preferredDisplayModeId
yerine setFrameRate()
. setFrameRate()
işlevinin kullanılması daha kolaydır, çünkü uygulamanın
belirli bir kare hızına sahip modu bulmak için görüntü modları listesinden yararlanın.
setFrameRate()
, uyumlu bir seçim yapması için platforma daha fazla fırsat sunar
birden fazla yüzeyin olduğu senaryolarda kare hızı
farklı kare hızlarında görüntülenebilir. Örneğin, iki uygulamanın aynı olduğu bir senaryoyu
Pixel 4'te bölünmüş ekran modunda çalışan (bir uygulamanın 24 Hz video oynattığı)
diğeri ise kullanıcıya kaydırılabilir bir liste gösteriyor. Pixel 4 iki cihazı destekler
görüntü yenileme hızları: 60 Hz ve 90 Hz. preferredDisplayModeId
API'yi kullanarak,
video yüzeyi 60 Hz veya 90 Hz seçilmeye zorlanır. Video yüzeyi, setFrameRate()
işlevini 24 Hz ile çağırarak platforma kaynak videonun kare hızı hakkında daha fazla bilgi verir. Bu sayede platform, görüntü yenileme hızı için 90 Hz'i seçebilir. Bu, söz konusu senaryoda 60 Hz'den daha iyidir.
Bununla birlikte, preferredDisplayModeId
işlevinin kullanılması gereken senaryolar da vardır.
yerine setFrameRate()
kullanabilirsiniz. Örneğin:
- Uygulama, çözünürlüğü veya diğer ekran modu ayarlarını değiştirmek istiyorsa
preferredDisplayModeId
değerini kullanın. - Platform yalnızca şu çağrıya yanıt olarak görüntü modlarını değiştirir:
Mod anahtarı hafifse ve çok düşük değilse
setFrameRate()
fark edebilirsiniz. Uygulama, ekranı yenilemeyi tercih ederse yoğun mod anahtarı gerektirse bile (örneğin, Android TV'de cihaz)preferredDisplayModeId
kullanın. - Görüntünün, uygulamanın kare hızının bir katı hızda çalışmasını kaldıramayan uygulamalar (bu durumda her karede zaman damgası ayarlaması gerekir)
preferredDisplayModeId
değerini kullanmalıdır.
setFrameRate() ve preferredRefreshRate
WindowManager.LayoutParams#preferredRefreshRate
, uygulamanın penceresinde tercih edilen bir kare hızı belirler. Bu hız, penceredeki tüm yüzeyler için geçerlidir. Uygulama, planlayıcıya uygulamanın amaçlanan kare hızıyla ilgili daha iyi bir ipucu vermek için setFrameRate()
'e benzer şekilde, cihazın desteklediği yenileme hızlarından bağımsız olarak tercih ettiği kare hızını belirtmelidir.
preferredRefreshRate
, setFrameRate()
kullanan yüzeyler için yoksayılır. İçinde
genel kullanım için setFrameRate()
kullanın.
preferredRefreshRate ve preferredDisplayModeId
Uygulamalar yalnızca tercih edilen yenileme hızını değiştirmek istiyorsa preferredDisplayModeId
yerine preferredRefreshRate
kullanılması tercih edilir.
setFrameRate() işlevini çok sık çağırmaktan kaçınma
setFrameRate()
çağrısı performans açısından çok maliyetli olmasa da uygulamaların setFrameRate()
çağrısını her karede veya saniyede birden çok kez çağırmaktan kaçınması gerekir. setFrameRate()
numaralı telefona yapılan aramaların,
yenileme hızında gösterilir. Bu da geçiş sırasında kare düşüşüne neden olabilir.
Doğru kare hızını önceden belirlemeniz ve
Bir kez setFrameRate()
.
Oyunlar veya video dışı diğer uygulamalar için kullanım
setFrameRate()
API'nin başlıca kullanım alanı video olsa da
diğer uygulamalar için kullanılır. Örneğin, 60 Hz'den daha yüksek bir hızda çalışmayı amaçlayan (güç kullanımını azaltmak ve daha uzun oyun oturumları elde etmek için) bir oyun Surface.setFrameRate(60, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT)
işlevini çağırabilir. Bu sayede, varsayılan olarak 90 Hz'de çalışan bir cihaz, oyun etkinken 60 Hz'de çalışır. Böylece, oyun 60 Hz'de çalışırken ekran 90 Hz'de çalışıyorsa oluşabilecek takılmalar önlenir.
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE kullanımı
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
yalnızca video uygulamaları için tasarlanmıştır. Örneğin,
video dışı kullanım için FRAME_RATE_COMPATIBILITY_DEFAULT
kullanın.
Kare hızını değiştirmek için strateji seçme
- Aşağıdaki gibi uzun süreli videoları görüntülerken uygulamaların
filmler,
setFrameRate(
fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS)
'yi ara Burada fps, videonun kare hızıdır. CHANGE_FRAME_RATE_ALWAYS
ilesetFrameRate()
çağıran uygulamaları kesinlikle önermeyiz Video oynatmanın birkaç dakika veya daha kısa sürmesini beklediğiniz durumlarda.
Video oynatma uygulamaları için örnek entegrasyon
Video oynatma uygulamalarına yenileme hızı anahtarlarını entegre etmek için aşağıdaki adımları uygulamanız önerilir:
changeFrameRateStrategy
değerine karar verin:- Film gibi uzun bir videoyu oynatıyorsanız
MATCH_CONTENT_FRAMERATE_ALWAYS
simgesini kullanın. - Film fragmanı gibi kısa bir video oynatıyorsanız
CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS
düğmesini kullanın.
- Film gibi uzun bir videoyu oynatıyorsanız
changeFrameRateStrategy
CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS
ise 4. adıma geçin.- Kesintisiz olmayan yenileme hızı değişiminin gerçekleşip gerçekleşmediğini kontrol ederek
iki gerçeğin de doğru olduğunu
- Mevcut yenileme hızından (C olarak adlandıralım) videonun kare hızına (V olarak adlandıralım) sorunsuz geçiş yapılamaz. C ve V farklıysa ve
Display.getMode().getAlternativeRefreshRates
, V'nin bir katını içermiyorsa bu durum söz konusudur. - Kullanıcı, yenileme hızı değişikliklerinin sorunsuz olmayan sürümünü etkinleştirmişse Google'da
DisplayManager.getMatchContentFrameRateUserPreference
MATCH_CONTENT_FRAMERATE_ALWAYS
değerini döndürür
- Mevcut yenileme hızından (C olarak adlandıralım) videonun kare hızına (V olarak adlandıralım) sorunsuz geçiş yapılamaz. C ve V farklıysa ve
- Geçiş sorunsuz olacaksa aşağıdakileri yapın:
setFrameRate
numaralı telefonu arayın vefps
,FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
, vechangeFrameRateStrategy
(buradafps
, videonun kare hızıdır).- Video oynatmayı başlat
- Sorunsuz olmayan bir mod değişikliği gerçekleşmek üzereyse aşağıdakileri yapın:
- Kullanıcıyı bilgilendirmek için kullanıcı deneyimini gösterin. Kullanıcının bu kullanıcı deneyimini kapatıp 5.d adımında ek gecikmeyi atlayabileceği bir yöntem uygulamanızı öneririz. Bunun nedeni, önerilen gecikmenin daha hızlı geçiş süreleri gösteren ekranlarda gerekenden daha uzun olmasıdır.
setFrameRate
numaralı telefonu arayın vefps
,FRAME_RATE_COMPATIBILITY_FIXED_SOURCE
, veCHANGE_FRAME_RATE_ALWAYS
Buradafps
videonun kare hızıdır.onDisplayChanged
geri aramasını bekleyin.- Mod geçişinin tamamlanması için 2 saniye bekleyin.
- Video oynatmayı başlat
Sorunsuz geçişi yalnızca destekleyen sözde kod şu şekildedir:
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
transaction.setFrameRate(surfaceControl,
contentFrameRate,
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
transaction.apply();
beginPlayback();
Yukarıda açıklandığı gibi sorunsuz ve sorunsuz olmayan geçişleri destekleyen sözde kod şu şekildedir:
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
if (isSeamlessSwitch(contentFrameRate)) {
transaction.setFrameRate(surfaceControl,
contentFrameRate,
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
transaction.apply();
beginPlayback();
} else if (displayManager.getMatchContentFrameRateUserPreference()
== MATCH_CONTENT_FRAMERATE_ALWAYS) {
showRefreshRateSwitchUI();
sleep(shortDelaySoUserSeesUi);
displayManager.registerDisplayListener(…);
transaction.setFrameRate(surfaceControl,
contentFrameRate,
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
CHANGE_FRAME_RATE_ALWAYS);
transaction.apply();
waitForOnDisplayChanged();
sleep(twoSeconds);
hideRefreshRateSwitchUI();
beginPlayback();
}