Gdy na Androidzie inicjowana jest animacja, często zwiększa się częstotliwość odświeżania ekranu, aby zapewnić płynne działanie. W przypadku małych animacji, takich jak paski postępu czy wizualizatory dźwięku, wysoka częstotliwość odświeżania jest niepotrzebna i powoduje duże zużycie energii.
Od Androida 15 dzięki funkcji adaptacyjnej częstotliwości odświeżania (ARR) urządzenia mogą zmniejszyć czas przebywania na ekranie w trybie wysokiej częstotliwości odświeżania w 2 sposoby:
- Dzięki nowym optymalizacjom zarządzania liczbą klatek na platformie aplikacje mogą renderować z niższą liczbą klatek na sekundę domyślnie i przełączać się na większą liczbę klatek tylko w razie potrzeby.
- Częstotliwość odświeżania wyświetlacza dynamicznie dopasowuje szybkość renderowania treści bez korzystania z janka.
Większość aplikacji powinna korzystać z ARR bez żadnych modyfikacji, ale w razie potrzeby możesz zastąpić domyślne zachowanie częstotliwości klatek.
Na tej stronie znajdziesz informacje na te tematy:
- Sposób określania liczby klatek na sekundę w przypadku każdej widoczności.
- Ogólna zasada dotycząca ARR określa szybkość klatek.
- Jak ręcznie zastąpić domyślną liczbę klatek na sekundę.
Mechanizm wyświetlania głosowania
W systemie View w Androidzie każdy View w hierarchii interfejsu może określić preferowaną liczbę klatek na sekundę. Te preferencje są zbierane i łączone, aby określić ostateczną liczbę klatek na sekundę dla każdej klatki. Osiąga się to za pomocą mechanizmu głosowania, w którym każde wyświetlenie głosuje na podstawie atrybutu częstotliwości klatek, który może być kategorią lub określoną częstotliwością. Widoki zwykle głosują, gdy są wyświetlane lub aktualizowane. Te głosy są łączone, aby określić ostateczną liczbę klatek, która jest następnie wysyłana do warstwy niższego poziomu jako wskazówka dotycząca renderowania.
Obecnie większość widoków ma domyślnie ustawioną „normalną” liczbę klatek na sekundę, która często wynosi 60 Hz. Aby uzyskać wyższą liczbę klatek na sekundę, możesz użyć odpowiednich interfejsów API, aby dostosować ustawienia. System zazwyczaj wybiera najwyższą liczbę klatek na sekundę. Więcej informacji o korzystaniu z tych interfejsów API znajdziesz w sekcji Ustawianie częstotliwości klatek lub kategorii. Ogólne zasady dotyczące częstotliwości wyświetlania reklam są opisane w sekcji Ogólne zasady dotyczące ARR.
Kategorie liczby klatek
W klasie View
dostępne są różne kategorie szybkości klatek, które można wykorzystać w głosowaniu. Opis każdej kategorii:
REQUESTED_FRAME_RATE_CATEGORY_DEFAULT
: ta wartość może być ustawiona tak, aby powrócić do zachowania domyślnego, co oznacza, że ta widoczność nie ma danych o częstotliwości klatek.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE
: widok nie będzie wpływać na częstotliwość klatek. Oznacza to, że nawet jeśli widok jest aktywny, framework nie będzie go uwzględniać przy określaniu częstotliwości klatek.REQUESTED_FRAME_RATE_CATEGORY_NORMAL
: wskazuje średnią liczbę klatek na sekundę odpowiednią do animacji, które nie wymagają wyższej liczby klatek na sekundę lub nie korzystają z płynności. Zwykle jest to 60 Hz lub zbliżone do tego.REQUESTED_FRAME_RATE_CATEGORY_HIGH
: wskazuje liczbę klatek na sekundę odpowiednią dla animacji, które wymagają wysokiej liczby klatek na sekundę. Może to zwiększyć płynność, ale też zużycie energii.
Wyświetl głosy tylko wtedy, gdy wymagają one ponownego narysowania. Ostateczna liczba klatek na sekundę jest określana na podstawie najwyższego głosu. Jeśli na przykład wszystkie głosy są na „Normalne”, wybrana jest opcja „Normalne”. Jeśli głosy „Normalnie” i „Wysoko” wystąpią jednocześnie, wybrana zostanie opcja „Wysoko”.
Liczba klatek
Oprócz kategorii częstotliwości klatek widok może też określać preferowaną częstotliwość klatek, np. 30, 60 lub 120 Hz. Gdy głosy dotyczące częstotliwości klatek są różne, ostateczna częstotliwość jest określana według tych reguł:
- Wielokrotności: jeśli wybrane częstotliwości klatek są wielokrotnościami siebie nawzajem, wybrana zostanie najwyższa wartość. Jeśli na przykład są 2 głosy – 30 Hz i 90 Hz – jako ostateczna częstotliwość klatek zostanie wybrana wartość 90 Hz.
- Nie są wielokrotnościami siebie nawzajem:
- Jeśli którykolwiek z głosów jest wyższy niż 60 Hz, jest uznawany za głos „wysoki”.
- Jeśli wszystkie głosy mają częstotliwość 60 Hz lub niższą, są uznawane za głosy „normalne”.
Dodatkowo, jeśli występuje kombinacja wartości liczby klatek i kategorii liczby klatek, to wyższa wartość zwykle określa ostateczną liczbę klatek. Na przykład w przypadku kombinacji głosowania 60 Hz i głosowania „Wysoka” lub głosowania 120 Hz i głosowania „Normalna” częstotliwość renderowania jest zwykle ustawiona na 120 Hz.
Oprócz głosów z aplikacji do warstwy niższego poziomu mogą być wysyłane inne wskazówki z różnych komponentów w ramach tego samego kadru. Wiele z nich może pochodzić z elementów interfejsu użytkownika, takich jak panel powiadomień, pasek stanu czy pasek nawigacyjny. Ostateczne wartości częstotliwości klatek są określane na podstawie głosów z wielu komponentów.
Ustaw liczbę klatek lub kategorię
W pewnych okolicznościach możesz mieć preferowaną liczbę klatek na View. Jeśli animacja nie jest płynna, możesz na przykład ustawić preferowaną liczbę klatek na „Wysoka”, aby zwiększyć liczbę klatek na sekundę. Dodatkowo, jeśli na filmie jest animacja powolna lub statyczna (zazwyczaj odtwarzana z częstotliwością 24 lub 30 Hz), możesz preferować odtwarzanie animacji z niższą częstotliwością niż „Normalna”, aby zmniejszyć zużycie energii.
Aby określić preferowaną częstotliwość klatek lub kategorię danego widoku, możesz użyć interfejsów API setRequestedFrameRate()
i 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);
Przykład użycia znajdziesz w sekcji TextureView
.
Ogólne zasady dotyczące ARR
W poprzedniej sekcji wspomnieliśmy, że większość animacji jest domyślnie wyświetlana z częstotliwością 60 Hz, ponieważ w przypadku każdej widoczności preferowana częstotliwość klatek jest ustawiona na „Normalna”. Są jednak wyjątki, w których przypadku liczba klatek jest zwiększana do „Wysoka”, aby zapewnić płynniejsze animacje.
Ogólne zasady dotyczące ARR:
- Touch boost (wzmocnienie dotyku): gdy wykryto zdarzenie dotyku (
MotionEvent.ACTION_DOWN
), częstotliwość odświeżania jest przez pewien czas po zwolnieniu dotyku zwiększana do „High” (wysoka), aby zachować responsywność. - Gesty rzutu: gesty rzutu są obsługiwane inaczej – częstotliwość odświeżania zmniejsza się stopniowo wraz ze spowolnieniem prędkości rzutu. Szczegółowe informacje o tym zachowaniu znajdziesz w sekcji Ulepszenie przewijania.
- Uruchamianie aplikacji i przechodzenie między oknami: aby zapewnić płynne działanie, w okresie uruchamiania aplikacji, inicjowania okien i przechodzenia między nimi częstotliwość odświeżania jest również zwiększana.
- Animacje: animacje, które obejmują ruch lub zmiany rozmiaru, automatycznie otrzymują wyższą częstotliwość odświeżania, aby zwiększyć płynność podczas zmiany położenia lub rozmiaru widoku.
SurfaceView
iTextureView
: liczba klatek ustawiona w sposób jawny wTextureView
iSurfaceView
jest uwzględniana i odpowiednio stosowana.
Włączanie i wyłączanie wzmocnienia dotyku
Możesz włączyć lub wyłączyć funkcję Touch Boost na poziomie Window
. Domyślnie, gdy użytkownik dotyka ekranu i odsuwa od niego palec, przez pewien czas zwiększa się szybkość renderowania. Interfejsy API setFrameRateBoostOnTouchEnabled()
i getFrameRateBoostOnTouchEnabled()
umożliwiają zapobieganie zwiększaniu szybkości renderowania po dotknięciu określonego elementu 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()
Usprawnienie przewijania
Jednym z głównych zastosowań dynamicznego optymalizowania częstotliwości klatek jest poprawa płynności przewijania. Wiele aplikacji wymaga od użytkowników przesunięcia palcem w górę, aby wyświetlić nowe treści. Ulepszenie przewijania ARR dostosowuje dynamicznie częstotliwość odświeżania, gdy gest przesuwania spowalnia, stopniowo zmniejszając częstotliwość klatek. Umożliwia to wydajniejsze renderowanie przy jednoczesnym zachowaniu płynnego przewijania.
To ulepszenie dotyczy przede wszystkim przewijanych komponentów interfejsu, takich jak ScrollView
, ListView
i GridView
. Nie wszystkie implementacje niestandardowe mogą z niego korzystać.
Funkcja przewijania ARR jest dostępna w przypadku RecyclerView
i NestedScrollView
. Aby włączyć tę funkcję w aplikacji, przejdź na najnowsze wersje AndroidX.recyclerview
i AndroidX.core
. Szczegółowe informacje znajdziesz w tabeli poniżej.
Biblioteka |
Wersja |
|
1.4.0 |
|
1.15.0 |
Ustawianie informacji o prędkości
Jeśli masz niestandardowy element przewijania i chcesz korzystać z funkcji przewijania, wywołuj funkcję setFrameContentVelocity()
w każdej klatce podczas płynnego przewijania lub przeciągania. Przykładowy fragment kodu:
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()
Więcej przykładów znajdziesz w artykule RecyclerView
i ScrollView
. Aby prawidłowo ustawić prędkość, oblicz prędkość treści (piksele na sekundę) ręcznie, jeśli wymaganych informacji nie można uzyskać z Scroller
ani OverScroller
.
Pamiętaj, że jeśli metody setFrameContentVelocity()
i getFrameContentVelocity()
są wywoływane w przypadku widoków, które nie są elementami przewijanymi, nie będą miały żadnego wpływu, ponieważ ruch automatycznie powoduje zwiększenie częstotliwości wyświetlania klatek zgodnie z bieżącymi zasadami.
Informacje o szybkości są kluczowe dla dostosowywania szybkości renderowania. Weź pod uwagę gest przesunięcia. Na początku prędkość wyrzutu może być wysoka, co wymaga wyższej częstotliwości renderowania, aby zapewnić płynność. W miarę wykonywania gestu prędkość maleje, co pozwala zmniejszyć częstotliwość renderowania.
Włączanie i wyłączanie ARR
ARR jest domyślnie włączona, aby zwiększyć energooszczędność. Możesz wyłączyć tę funkcję, ale nie jest to zalecane, ponieważ aplikacja będzie zużywać więcej energii. Wyłącz tę funkcję tylko wtedy, gdy napotkasz problemy, które znacząco wpływają na wrażenia użytkowników.
Aby włączyć lub wyłączyć ARR, użyj interfejsu setFrameRatePowerSavingsBalanced()
API w kontekście Window
lub interfejsu isFrameRatePowerSavingsBalanced()
API w pliku styles.xml
.
Ten fragment kodu pokazuje, jak włączyć lub wyłączyć ARR w 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()
Aby wyłączyć ARR w pliku styles.xml
, dodaj do stylu w pliku res/values/styles.xml
ten element:
<style name="frameRatePowerSavingsBalancedDisabled">
<item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
</style>