Mengoptimalkan kecepatan frame dengan kecepatan refresh adaptif

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 visualiser audio, kecepatan refresh tinggi ini tidak diperlukan, dan menghasilkan konsumsi daya yang tinggi.

Mulai Android 15, dengan fitur kecepatan refresh adaptif (ARR), perangkat yang diaktifkan dapat mengurangi residensi kecepatan refresh tinggi di dua bidang:

  • Dengan pengoptimalan pengelolaan kecepatan frame platform baru, aplikasi dapat merender pada kecepatan frame yang lebih rendah secara default dan hanya meningkatkan kecepatan frame menjadi tinggi jika diperlukan.
  • Kecepatan refresh layar secara dinamis cocok dengan kecepatan render konten tanpa jank.

Meskipun sebagian besar aplikasi akan mendapatkan manfaat dari ARR tanpa perubahan apa pun, Anda juga dapat mengganti perilaku kecepatan frame default sesuai kebutuhan.

Halaman ini menjelaskan hal berikut:

  • Cara setiap kecepatan frame View ditentukan.
  • Kebijakan umum untuk 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 mengekspresikan kecepatan frame yang diinginkan. Preferensi ini dikumpulkan dan digabungkan untuk menentukan kecepatan frame akhir untuk setiap frame. Hal ini dicapai melalui mekanisme pemungutan suara dengan setiap View memberikan suara berdasarkan atribut kecepatan frame-nya, yang dapat berupa kategori atau kecepatan tertentu. Tampilan biasanya memberikan suara 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 View ditetapkan secara default ke kecepatan frame "Normal", yang sering 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 kategori atau kecepatan frame. 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 View ini tidak memiliki data untuk kecepatan frame.
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE: View secara eksplisit tidak akan memengaruhi kecepatan frame. Artinya, meskipun View aktif, framework tidak akan mempertimbangkannya saat menentukan kecepatan frame
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL: Menunjukkan kecepatan frame tengah yang cocok untuk animasi yang tidak memerlukan kecepatan frame yang lebih tinggi, atau tidak mendapatkan manfaat dari kelancaran yang tinggi. Biasanya 60 Hz atau mendekatinya.
  • 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 memberikan suara jika memerlukan penggambaran ulang. Kecepatan frame akhir ditentukan oleh suara tertinggi. Misalnya, jika semua suara untuk "Normal", "Normal" akan dipilih. Jika suara "Normal" dan "Tinggi" terjadi, "Tinggi" akan dipilih.

Kecepatan frame

Selain kategori kecepatan frame, Tampilan juga dapat menentukan kecepatan frame yang diinginkan, seperti 30, 60, atau 120 Hz. Saat beberapa suara kecepatan frame diberikan, kecepatan frame akhir ditentukan oleh aturan berikut:

  • Kelipatan satu sama lain: Jika kecepatan frame yang dipilih merupakan kelipatan satu sama lain, nilai tertinggi akan dipilih. Misalnya, jika ada dua suara - 30 Hz dan 90 Hz — 90 Hz dipilih sebagai kecepatan frame akhir.
  • Bukan kelipatan satu sama lain:
    • Jika salah satu suara lebih besar dari 60 Hz, suara tersebut akan dihitung sebagai suara "Tinggi".
    • Jika semua suara adalah 60 Hz atau lebih rendah, suara tersebut 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 render 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 darinya dapat berasal dari komponen UI Sistem, seperti bayangan 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 View. Misalnya, Anda dapat menetapkan kecepatan frame yang diinginkan ke "Tinggi" untuk View 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 dapat memilih animasi untuk berjalan pada kecepatan yang lebih rendah dari "Normal" untuk mengurangi konsumsi daya.

Anda dapat menggunakan API setRequestedFrameRate() dan getRequestedFrameRate() untuk menentukan kecepatan frame atau kategori yang diinginkan dari 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 telah 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 dinaikkan ke "Tinggi" untuk memastikan animasi yang lebih halus.

Kebijakan ARR umum adalah sebagai berikut:

  • Peningkatan sentuh: Saat peristiwa sentuh (MotionEvent.ACTION_DOWN) terdeteksi, kecepatan refresh akan ditingkatkan ke "Tinggi" selama beberapa waktu setelah sentuhan dilepaskan untuk mempertahankan responsivitas.
  • Gestur ayun: Gestur ayun ditangani secara berbeda—kecepatan refresh turun secara bertahap saat kecepatan ayun melambat. Anda dapat menemukan detail tentang perilaku ini di bagian Peningkatan scroll.
  • Peluncuran aplikasi dan transisi jendela: Kecepatan refresh juga ditingkatkan selama beberapa waktu selama peluncuran aplikasi, inisialisasi jendela, dan transisi jendela untuk memastikan pengalaman visual yang lancar.
  • Animasi: Animasi yang melibatkan gerakan atau perubahan ukuran secara otomatis menerima kecepatan refresh yang lebih tinggi untuk meningkatkan kelancaran saat posisi atau ukuran Tampilan berubah.
  • SurfaceView dan TextureView: Kecepatan frame yang ditetapkan secara eksplisit untuk TextureView dan SurfaceView akan dipatuhi dan diterapkan sesuai kebutuhan.

Mengaktifkan dan menonaktifkan peningkatan sentuh

Anda dapat mengaktifkan dan/atau menonaktifkan peningkatan sentuh di tingkat Window. Secara default, saat pengguna menyentuh dan mengangkat jari dari layar, kecepatan render akan meningkat selama beberapa waktu. API setFrameRateBoostOnTouchEnabled() dan getFrameRateBoostOnTouchEnabled() memungkinkan Anda mencegah kecepatan render meningkat 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 scroll

Salah satu kasus penggunaan utama untuk mengoptimalkan kecepatan frame secara dinamis adalah untuk meningkatkan pengalaman scroll (ayunkan). Banyak aplikasi sangat mengandalkan pengguna yang menggeser ke atas untuk melihat konten baru. Peningkatan scroll ARR secara dinamis menyesuaikan kecepatan refresh saat gestur ayun 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 scroll 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

Version

AndroidX.recyclerview

1.4.0

AndroidX.core

1.15.0

Menetapkan informasi kecepatan

Jika Anda memiliki komponen yang dapat di-scroll kustom dan ingin memanfaatkan fitur scroll, panggil setFrameContentVelocity() di setiap frame saat scroll atau lempar halus. 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 menetapkan 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 View yang bukan komponen yang 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 render. Misalnya, pertimbangkan gestur ayun. Pada awalnya, kecepatan ayun dapat tinggi, sehingga memerlukan kecepatan render yang lebih tinggi untuk memastikan kelancaran. Seiring gestur berlangsung, kecepatan menurun, sehingga kecepatan render dapat diturunkan.

Mengaktifkan dan menonaktifkan ARR

ARR diaktifkan secara default untuk meningkatkan efisiensi daya. Meskipun Anda dapat menonaktifkan fitur ini, sebaiknya jangan melakukannya karena aplikasi akan menggunakan lebih banyak daya. Hanya pertimbangkan untuk menonaktifkan fitur ini jika Anda mengalami masalah yang memengaruhi pengalaman pengguna secara signifikan.

Untuk mengaktifkan atau menonaktifkan ARR, gunakan setFrameRatePowerSavingsBalanced() API di Window, atau gunakan isFrameRatePowerSavingsBalanced() API melalui file styles.xml.

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>