Saat animasi dimulai di Android, layar sering kali ditingkatkan ke kecepatan refresh maksimum untuk memastikan pengalaman yang lancar. Untuk animasi kecil seperti status progres dan visualisator audio, kecepatan refresh tinggi ini tidak diperlukan, dan mengakibatkan konsumsi daya yang tinggi.
Mulai Android 15, dengan fitur kecepatan refresh adaptif (ARR), perangkat yang diaktifkan dapat mengurangi penggunaan kecepatan refresh tinggi dalam dua hal:
- Dengan pengoptimalan pengelolaan kecepatan frame platform baru, aplikasi dapat merender pada kecepatan frame yang lebih rendah secara default dan hanya meningkatkan ke kecepatan frame tinggi jika diperlukan.
- Kecepatan refresh layar secara dinamis cocok dengan kecepatan rendering konten tanpa jank.
Meskipun sebagian besar aplikasi akan mendapatkan manfaat dari ARR tanpa modifikasi apa pun, Anda juga dapat mengganti perilaku kecepatan frame default sesuai kebutuhan.
Halaman ini menjelaskan hal berikut:
- Cara kecepatan frame setiap Tampilan ditentukan.
- Kebijakan umum tentang cara ARR menentukan kecepatan frame yang ditetapkan.
- Cara mengganti perilaku kecepatan frame default secara manual.
Mekanisme pemungutan suara View
Dalam sistem View Android, setiap View dalam hierarki UI dapat menyatakan kecepatan frame yang diinginkannya. Preferensi ini dikumpulkan dan digabungkan untuk menentukan kecepatan frame akhir untuk setiap frame. Hal ini dicapai melalui mekanisme pemberian suara di mana setiap Tampilan memberikan suara berdasarkan atribut kecepatan frame-nya, yang dapat berupa kategori atau kecepatan tertentu. Tampilan biasanya memilih saat digambar atau diperbarui. Suara ini digabungkan untuk menentukan kecepatan frame akhir, yang kemudian dikirim ke lapisan tingkat bawah sebagai petunjuk untuk rendering.
Saat ini, sebagian besar Tampilan secara default menggunakan kecepatan frame "Normal", yang sering kali ditetapkan ke 60 Hz. Untuk kecepatan frame yang lebih tinggi, Anda dapat menggunakan API tertentu untuk menyesuaikan preferensi, dengan sistem yang umumnya memilih kecepatan frame tertinggi. Untuk mengetahui informasi selengkapnya tentang penggunaan API ini, lihat bagian Menetapkan kecepatan frame atau kategori. Kebijakan umum terkait kecepatan frame dijelaskan di bagian Kebijakan ARR umum.
Kategori kecepatan frame
Di class View
, ada berbagai kategori kecepatan frame yang dapat digunakan dalam pemungutan suara. Deskripsi setiap kategori adalah sebagai berikut:
REQUESTED_FRAME_RATE_CATEGORY_DEFAULT
: Nilai ini dapat disetel untuk kembali ke perilaku default, yang menunjukkan bahwa Tampilan ini tidak memiliki data untuk kecepatan frame.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE
: Tampilan tidak akan secara eksplisit memengaruhi kecepatan frame. Artinya, meskipun Tampilan aktif, framework tidak akan mempertimbangkannya saat menentukan kecepatan frameREQUESTED_FRAME_RATE_CATEGORY_NORMAL
: Menunjukkan kecepatan frame tengah yang cocok untuk animasi yang tidak memerlukan kecepatan frame yang lebih tinggi, atau tidak diuntungkan dengan kelancaran yang tinggi. Biasanya 60 Hz atau mendekati 60 Hz.REQUESTED_FRAME_RATE_CATEGORY_HIGH
: Menunjukkan kecepatan frame yang sesuai untuk animasi yang memerlukan kecepatan frame tinggi, yang dapat meningkatkan kelancaran tetapi juga dapat meningkatkan penggunaan daya.
Tampilan hanya memilih jika perlu digambar ulang. Kecepatan frame akhir ditentukan oleh suara terbanyak. Misalnya, jika semua suara memilih "Normal", "Normal" dipilih. Jika suara "Normal" dan "Tinggi" terjadi, "Tinggi" akan dipilih.
Kecepatan frame
Selain kategori kecepatan frame, Tampilan juga dapat menentukan kecepatan frame pilihan, seperti 30, 60, atau 120 Hz. Jika beberapa pilihan kecepatan frame diberikan, kecepatan frame akhir ditentukan oleh aturan berikut:
- Kelipatan satu sama lain: Jika kecepatan frame yang dipilih adalah kelipatan satu sama lain, nilai tertinggi akan dipilih. Misalnya, jika ada dua pilihan kecepatan frame - 30 Hz dan 90 Hz — 90 Hz akan dipilih sebagai kecepatan frame akhir.
- Bukan kelipatan satu sama lain:
- Jika salah satu suara lebih besar dari 60 Hz, suara tersebut dihitung sebagai suara "Tinggi".
- Jika semua suara adalah 60 Hz atau lebih rendah, maka akan dihitung sebagai suara "Normal".
Selain itu, jika ada kombinasi nilai kecepatan frame dan kategori kecepatan frame, nilai yang lebih tinggi biasanya menentukan kecepatan render akhir. Misalnya, dengan kombinasi suara 60 Hz dan suara "Tinggi", atau suara 120 Hz dan suara "Normal", kecepatan rendering biasanya akan disetel ke 120 Hz.
Selain suara dari aplikasi, mungkin juga ada petunjuk lain yang dikirim ke lapisan tingkat bawah dari berbagai komponen dalam frame yang sama. Banyak di antaranya dapat berasal dari komponen UI Sistem, seperti panel notifikasi, status bar, menu navigasi, dan lainnya. Nilai kecepatan frame akhir ditentukan berdasarkan suara dari beberapa komponen.
Menetapkan kecepatan frame atau kategori
Dalam situasi tertentu, Anda mungkin memiliki kecepatan frame pilihan untuk Tampilan. Misalnya, Anda dapat menyetel kecepatan frame pilihan ke "Tinggi" untuk Tampilan guna meningkatkan kecepatan frame jika animasi tampak tidak lancar. Selain itu, jika ada animasi lambat atau statis di atas video (biasanya diputar pada 24 atau 30 Hz), Anda mungkin lebih memilih animasi berjalan pada kecepatan yang lebih rendah daripada "Normal" untuk mengurangi konsumsi daya.
Anda dapat menggunakan API setRequestedFrameRate()
dan
getRequestedFrameRate()
untuk menetapkan kecepatan frame atau
kategori pilihan untuk View tertentu.
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);
Untuk contoh penggunaan, lihat TextureView
.
Kebijakan ARR umum
Di bagian sebelumnya, kita membahas bahwa sebagian besar animasi ditampilkan pada 60 Hz secara default, karena setiap View memiliki "Normal" yang ditetapkan sebagai kecepatan frame pilihan. Namun, ada pengecualian saat kecepatan frame ditingkatkan menjadi "Tinggi" untuk memastikan animasi yang lebih lancar.
Kebijakan ARR umum adalah sebagai berikut:
- Peningkatan sentuhan: Saat peristiwa sentuhan (
MotionEvent.ACTION_DOWN
) terdeteksi, kecepatan refresh ditingkatkan ke "Tinggi" selama beberapa waktu setelah sentuhan dilepaskan untuk mempertahankan responsivitas. - Gestur mengayunkan: Gestur mengayunkan ditangani secara berbeda—kecepatan refresh berkurang secara bertahap saat kecepatan mengayunkan melambat. Anda dapat menemukan detail tentang perilaku ini di bagian Peningkatan kualitas scrolling.
- Peluncuran aplikasi dan transisi jendela: Kecepatan refresh juga ditingkatkan selama beberapa waktu saat peluncuran aplikasi, inisialisasi jendela, dan transisi jendela untuk memastikan pengalaman visual yang lancar.
- Animasi: Animasi yang melibatkan perubahan gerakan atau ukuran secara otomatis menerima kecepatan refresh yang lebih tinggi untuk meningkatkan kelancaran saat posisi atau ukuran Tampilan berubah.
SurfaceView
danTextureView
: Kecepatan frame yang ditetapkan secara eksplisit untukTextureView
danSurfaceView
akan dipatuhi dan diterapkan dengan tepat.
Mengaktifkan dan menonaktifkan peningkatan sentuhan
Anda dapat mengaktifkan dan/atau menonaktifkan peningkatan sentuhan di tingkat Window
. Secara default, saat pengguna menyentuh dan mengangkat jari dari layar, kecepatan rendering akan meningkat selama beberapa waktu. API setFrameRateBoostOnTouchEnabled()
dan
getFrameRateBoostOnTouchEnabled()
memungkinkan Anda mencegah peningkatan
kecepatan rendering saat Window
tertentu disentuh.
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()
Peningkatan scrolling
Salah satu kasus penggunaan utama untuk mengoptimalkan kecepatan frame secara dinamis adalah untuk meningkatkan kualitas pengalaman men-scroll (menggeser). Banyak aplikasi sangat mengandalkan pengguna yang menggeser ke atas untuk melihat konten baru. Peningkatan kualitas scroll ARR secara dinamis menyesuaikan kecepatan refresh saat gestur mengayun melambat, sehingga secara bertahap mengurangi kecepatan frame. Hal ini memberikan rendering yang lebih efisien sekaligus mempertahankan scrolling yang lancar.
Peningkatan ini berlaku khusus untuk komponen UI yang dapat di-scroll, termasuk
ScrollView
, ListView
, dan GridView
, dan mungkin tidak tersedia untuk semua implementasi kustom.
Fitur scrolling ARR tersedia untuk RecyclerView
dan
NestedScrollView
. Untuk mengaktifkan fitur ini di aplikasi Anda, upgrade ke versi terbaru AndroidX.recyclerview
dan AndroidX.core
. Lihat tabel berikut untuk mengetahui detailnya.
Koleksi |
Versi |
|
1.4.0 |
|
1.15.0 |
Menetapkan informasi kecepatan
Jika Anda memiliki komponen scroll kustom dan ingin memanfaatkan fitur
scrolling, panggil setFrameContentVelocity()
di setiap frame saat
scrolling halus atau melempar. Lihat cuplikan kode berikut untuk mengetahui contohnya:
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()
Untuk contoh lainnya, lihat RecyclerView
dan
ScrollView
. Untuk menyetel kecepatan dengan benar, hitung kecepatan konten (piksel per detik) secara manual jika informasi yang diperlukan tidak dapat diperoleh dari Scroller
atau OverScroller
.
Perhatikan bahwa, jika setFrameContentVelocity()
dan
getFrameContentVelocity()
dipanggil pada komponen View yang tidak dapat di-scroll, keduanya tidak akan berpengaruh, karena gerakan secara otomatis memicu peningkatan kecepatan frame berdasarkan kebijakan saat ini.
Informasi kecepatan sangat penting untuk menyesuaikan kecepatan rendering. Misalnya, pertimbangkan gestur mengayunkan. Pada awalnya, kecepatan lemparan bisa tinggi, sehingga memerlukan kecepatan rendering yang lebih tinggi untuk memastikan kelancaran. Saat gestur berlangsung, kecepatan akan menurun, sehingga kecepatan rendering dapat diturunkan.
Mengaktifkan dan menonaktifkan ARR
ARR diaktifkan secara default untuk meningkatkan efisiensi daya. Meskipun Anda dapat menonaktifkan fitur ini, sebaiknya jangan dilakukan karena aplikasi akan menggunakan lebih banyak daya. Hanya pertimbangkan untuk menonaktifkan fitur ini jika Anda mengalami masalah yang sangat memengaruhi pengalaman pengguna.
Untuk mengaktifkan atau menonaktifkan ARR, gunakan
API setFrameRatePowerSavingsBalanced()
di Window
, atau gunakan
API isFrameRatePowerSavingsBalanced()
melalui file styles.xml
Anda.
Cuplikan berikut menunjukkan cara mengaktifkan atau menonaktifkan ARR di 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()
Untuk menonaktifkan ARR melalui file styles.xml
, tambahkan item
berikut ke gaya Anda di res/values/styles.xml
:
<style name="frameRatePowerSavingsBalancedDisabled">
<item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
</style>
ARR untuk Compose
Compose 1.9 juga menambahkan dukungan untuk rasio muat ulang adaptif.
Di sistem View, Anda menggunakan metode setRequestedFrameRate()
untuk
meminta kecepatan frame tertentu untuk View. Di Compose, pengubah baru memungkinkan Anda
menentukan kecepatan frame untuk composable. Pengubah ini berfungsi
mirip dengan setRequestedFrameRate()
, menerima nilai kecepatan frame positif (dalam Hz) atau kategori kecepatan frame yang telah ditentukan sebelumnya, FrameRateCategory
.
Tanda tangan untuk API adalah sebagai berikut:
Modifier.preferredFrameRate(frameRate: Float)
Modifier.preferredFrameRate(frameRateCategory: FrameRateCategory)
Dalam cuplikan di bawah, pengubah kecepatan frame baru (Modifier.requestedFrameRate(120f))
diterapkan ke composable Text
. Pengubah ini menyebabkan composable Text
meminta kecepatan frame pilihan 120 saat digambar atau dianimasikan (misalnya, dengan perubahan opasitas):
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
)
}
Kecepatan frame pilihan dari semua composable kemudian dikumpulkan dan
digabungkan untuk menentukan kecepatan frame akhir untuk setiap frame. Untuk mengetahui detail selengkapnya, lihat SetFrameRateSample
dan SetFrameRateCategorySample
.