Pengoptimalan memori sangat penting untuk memastikan performa yang lancar, mencegah error aplikasi, dan mempertahankan stabilitas sistem serta kesehatan platform. Meskipun penggunaan memori harus dipantau dan dioptimalkan di setiap aplikasi, perangkat aplikasi konten untuk TV memiliki tantangan khusus yang berbeda dari aplikasi Android standar untuk perangkat genggam.
Konsumsi memori yang tinggi dapat menyebabkan masalah pada perilaku aplikasi dan sistem termasuk:
- Aplikasi itu sendiri dapat menjadi lambat atau lambat, atau dalam kasus terburuk, dihentikan.
- Layanan sistem yang terlihat oleh pengguna (Dasbor Kontrol Volume, Setelan Gambar, Asisten Suara, dll.) menjadi sangat lambat atau mungkin tidak berfungsi sama sekali.
- Komponen sistem dapat dihentikan; komponen ini kemudian dimulai ulang, memicu lonjakan pertentangan resource ekstrem dan secara langsung memengaruhi aplikasi latar depan.
- Transisi ke Peluncur dapat tertunda secara signifikan, dan membuat aplikasi latar depan tampak tidak responsif hingga transisi selesai.
- Sistem dapat memasuki situasi pengambilan kembali langsung, yang menjeda sementara eksekusi thread sambil menunggu alokasi memori. Hal ini dapat terjadi pada thread apa pun seperti thread utama atau thread terkait codec yang berpotensi menyebabkan penurunan frame audio dan video, serta gangguan UI.
Pertimbangan memori di Perangkat TV
Perangkat TV biasanya memiliki memori yang jauh lebih kecil daripada ponsel atau tablet. Misalnya, konfigurasi yang dapat kita lihat di TV adalah RAM 1 GB dan resolusi video 1080p. Pada saat yang sama, sebagian besar aplikasi TV memiliki fitur yang serupa; sehingga memiliki implementasi dan tantangan yang sama. Kedua situasi ini menimbulkan masalah yang tidak terlihat di jenis perangkat dan aplikasi lain:
- Aplikasi TV media biasanya terdiri dari tampilan gambar berkisi dan gambar latar belakang layar penuh yang memerlukan pemuatan banyak gambar ke memori dalam waktu singkat
- Aplikasi TV memutar streaming multimedia yang memerlukan alokasi jumlah memori tertentu untuk memutar video dan audio serta memerlukan buffering media yang cukup untuk memastikan pemutaran yang lancar.
- Fitur media tambahan (pencarian, perubahan episode, perubahan trek audio, dll.) dapat menimbulkan tekanan memori tambahan jika tidak diterapkan dengan benar.
Memahami perangkat TV
Panduan ini terutama berfokus pada penggunaan memori aplikasi dan target memori untuk perangkat dengan RAM rendah.
Di perangkat TV, pertimbangkan karakteristik berikut:
- Memori perangkat: Jumlah Random Access Memory (RAM) yang diinstal perangkat.
- Resolusi UI perangkat: Resolusi yang digunakan perangkat untuk merender UI OS dan Aplikasi; biasanya lebih rendah dari resolusi video perangkat.
- Resolusi video: Resolusi maksimum yang dapat digunakan perangkat untuk memutar video.
Hal ini menyebabkan pengelompokan berbagai jenis perangkat dan cara memori harus digunakan olehnya.
Ringkasan perangkat TV
Memori perangkat | Resolusi video perangkat | Resolusi UI perangkat | isLowRAMDevice() |
---|---|---|---|
1 GB | 1080p | 720p | Ya |
1,5 GB | 2160p | 1080p | Ya |
≥1,5 GB | 1080p | 720p atau 1080p | Tidak* |
≥2 GB | 2160p | 1080p | Tidak* |
Perangkat TV dengan RAM rendah
Perangkat ini berada dalam situasi keterbatasan memori dan akan melaporkan
ActivityManager.isLowRAMDevice()
ke benar. Aplikasi yang berjalan di perangkat TV dengan RAM rendah perlu menerapkan
langkah-langkah kontrol memori tambahan.
Kami menganggap perangkat dengan karakteristik berikut termasuk dalam kategori ini:
- Perangkat 1 GB: RAM 1 GB, resolusi UI 720p/HD (1280x720), Resolusi video 1080p/FullHD (1920x1080)
- Perangkat 1,5 GB: RAM 1,5 GB, resolusi UI 1080p/FullHD (1920x1080), resolusi Video 2160p/UltraHD/4K (3840x2160)
- Situasi lain saat OEM menentukan flag
ActivityManager.isLowRAMDevice()
karena batasan memori tambahan.
Perangkat TV biasa
Perangkat ini tidak mengalami situasi tekanan memori yang signifikan. Kami menganggap perangkat ini memiliki karakteristik berikut:
- RAM ≥1,5 GB, UI 720p atau 1080p, dan resolusi video 1080p
- RAM ≥2 GB, UI 1080p, dan resolusi video 1080p atau 2160p
Hal ini tidak berarti aplikasi tidak boleh memperhatikan penggunaan memori di perangkat ini, karena beberapa penyalahgunaan memori tertentu masih dapat menghabiskan memori yang tersedia dan berperforma buruk.
Target memori di perangkat TV dengan RAM rendah
Saat mengukur memori di perangkat ini, sebaiknya pantau setiap bagian memori menggunakan profiler memori Android Studio. Aplikasi TV harus membuat profil penggunaan memori dan berupaya menempatkan kategorinya di bawah nilai minimum yang kami tentukan di bagian ini.
Di bagian Cara penghitungan memori, Anda akan menemukan penjelasan mendetail tentang angka memori yang dilaporkan. Untuk menentukan nilai minimum aplikasi TV, kita akan berfokus pada tiga kategori memori:
- Anonymous + Swap: Terdiri dari memori alokasi Java + Native + Stack di Android Studio.
- Grafis: Langsung dilaporkan di alat profiler. Umumnya terdiri dari tekstur grafis.
- File: Dilaporkan sebagai kategori "Code" + "Others" di Android Studio.
Dengan definisi ini, tabel berikut menunjukkan nilai maksimum yang harus digunakan setiap jenis grup memori:
Jenis memori | Tujuan | Target penggunaan (1 GB) |
---|---|---|
Anonim + Swap (Java + Native + Stack) | Digunakan untuk alokasi, buffering media, variabel, dan tugas lain yang membutuhkan banyak memori. | < 160 MB |
Grafik | Digunakan oleh GPU untuk tekstur dan menampilkan buffering terkait | 30-40 MB |
File | Digunakan untuk halaman dan file kode dalam memori. | 60-80 MB |
Total memori maksimum (Anon+Swap + Graphics + File) tidak boleh melebihi hal berikut:
- Total penggunaan memori 280 MB (Anon+Swap + Graphics + File) untuk perangkat RAM rendah 1 GB.
Sangat disarankan untuk tidak melebihi:
- Penggunaan memori sebesar 200 MB di (Anon+Swap + Graphics).
Memori file
Sebagai panduan umum untuk memori yang didukung file, perhatikan bahwa:
- Secara umum, memori file ditangani dengan baik oleh pengelolaan memori OS.
- Saat ini, kami belum menemukan bahwa hal ini menjadi penyebab utama tekanan memori.
Namun, saat menangani memori File secara umum:
- Jangan sertakan library yang tidak digunakan ke dalam build Anda, dan gunakan subset library kecil, bukan yang lengkap jika memungkinkan.
- Jangan biarkan file besar terbuka di memori dan lepaskan segera setelah Anda selesai menggunakannya.
- Minimalkan ukuran kode yang dikompilasi untuk class Java dan Kotlin, lihat panduan Menyingkat, meng-obfuscate, dan mengoptimalkan aplikasi.
Rekomendasi TV tertentu
Bagian ini memberikan rekomendasi spesifik untuk mengoptimalkan penggunaan memori di perangkat TV.
Memori grafis
Gunakan format dan resolusi gambar yang sesuai.
- Jangan memuat gambar dengan resolusi lebih tinggi dari resolusi UI perangkat. Misalnya, gambar 1080p harus diperkecil menjadi 720p di perangkat UI 720p.
- Gunakan bitmap yang didukung hardware jika memungkinkan.
- Di library seperti Glide, aktifkan
fitur
Downsampler.ALLOW_HARDWARE_CONFIG
yang dinonaktifkan secara default. Mengaktifkannya akan menghindari duplikasi bitmap yang akan berada di memori grafis dan memori anonim.
- Di library seperti Glide, aktifkan
fitur
- Hindari rendering perantara dan rendering ulang
- Hal ini dapat diidentifikasi dengan Android GPU Inspector:
- Lihat bagian "Tekstur" untuk gambar yang merupakan langkah menuju render akhir, bukan hanya elemen yang membentuknya, ini biasanya disebut "render perantara".
- Untuk aplikasi Android SDK, Anda sering kali dapat menghapusnya menggunakan
tanda tata letak
forceHasOverlappedRendering:false
untuk menonaktifkan render perantara untuk tata letak ini. - Lihat Menghindari Rendering Tumpang-Tindih pada rendering tumpang-tindih sebagai referensi yang bagus.
- Hindari memuat gambar placeholder jika memungkinkan, gunakan
@android:color/
atau@color
untuk tekstur placeholder. - Hindari penggabungan beberapa gambar di perangkat jika komposisi dapat dilakukan secara offline. Lebih memilih memuat gambar mandiri daripada melakukan komposisi gambar dari gambar yang didownload
- Ikuti panduan Menangani bitmap untuk menangani Bitmap dengan lebih baik.
Anon+Swap memory
Anon+Swap terdiri dari alokasi Native + Java + Stack di Android Studio
memory profiler. Gunakan
ActivityManager.isLowMemoryDevice()
untuk memeriksa apakah perangkat memiliki keterbatasan memori, dan beradaptasi dengan situasi ini
dengan mengikuti panduan ini.
- Media:
- Menentukan ukuran variabel untuk buffering media bergantung pada RAM
perangkat dan resolusi pemutaran video. Ini akan mencakup pemutaran video selama 1 menit:
- 40-60 MB untuk 1 GB / 1080p
- 60-80 MB untuk 1,5 GB / 1080p
- 80-100 MB untuk 1,5 GB / 2160p
- 100-120 MB untuk 2 GB / 2160p
- Membebaskan alokasi memori media saat mengubah episode untuk mencegah peningkatan jumlah total memori Anonim.
- Segera lepaskan dan hentikan resource media saat aplikasi Anda
dihentikan: Gunakan callback siklus proses
aktivitas untuk menangani resource audio dan video. Jika Anda bukan aplikasi audio,
hentikan pemutaran saat
onStop()
terjadi pada aktivitas Anda, simpan semua pekerjaan yang Anda lakukan, dan tetapkan resource untuk dirilis. Untuk menjadwalkan pekerjaan yang mungkin Anda perlukan nanti. Lihat bagian Tugas dan Alarm.- Anda dapat menggunakan komponen berbasis siklus proses
seperti
LiveData
danLifecycleOwner
untuk membantu Anda menangani panggilan siklus proses Aktivitas. - Agar pekerjaan Anda mendukung Siklus Proses, Anda juga dapat menggunakan coroutine Kotlin dan alur Kotlin.
- Anda dapat menggunakan komponen berbasis siklus proses
seperti
- Perhatikan memori buffering saat pencarian video: Developer
sering mengalokasikan konten mendatang tambahan selama 15-60 detik saat ingin
menyiapkan video untuk pengguna, tetapi hal ini akan menimbulkan overhead memori tambahan.
Secara umum, jangan mengambil buffer mendatang lebih dari 5 detik hingga pengguna
memilih posisi video baru. Jika Anda benar-benar perlu melakukan pra-buffer
waktu tambahan saat mencari, pastikan untuk:
- Alokasikan buffering pencarian terlebih dahulu dan gunakan kembali.
- Ukuran buffering tidak boleh lebih besar dari 15-25 MB (bergantung pada memori perangkat).
- Menentukan ukuran variabel untuk buffering media bergantung pada RAM
perangkat dan resolusi pemutaran video. Ini akan mencakup pemutaran video selama 1 menit:
- Alokasi:
- Gunakan panduan memori grafis untuk memastikan
Anda tidak menduplikasi gambar di memori Anonim
- Gambar sering kali menjadi pengguna memori terbesar sehingga duplikasinya dapat memberikan banyak tekanan pada perangkat. Hal ini terutama berlaku selama navigasi gridview gambar yang berat.
- Lepaskan alokasi dengan menghapus referensinya saat memindahkan layar: Pastikan tidak ada referensi ke bitmap dan objek yang tertinggal.
- Gunakan panduan memori grafis untuk memastikan
Anda tidak menduplikasi gambar di memori Anonim
- Library:
- Profil alokasi memori dari library saat menambahkan library baru, karena library tersebut juga dapat memuat library tambahan, yang juga dapat membuat alokasi dan membuat Binding.
- Jaringan:
- Jangan melakukan pemblokiran panggilan jaringan selama startup aplikasi, karena akan memperlambat waktu startup aplikasi dan membuat overhead memori tambahan saat peluncuran, saat memori sangat dibatasi oleh pemuatan aplikasi. Tampilkan layar pemuatan atau pembuka terlebih dahulu dan lakukan permintaan jaringan setelah UI diterapkan.
Binding
Binding memperkenalkan overhead memori tambahan karena membawa aplikasi lain ke dalam memori atau meningkatkan konsumsi memori aplikasi terikat (jika sudah ada di memori ) untuk memfasilitasi panggilan API. Akibatnya, hal ini mengurangi memori yang tersedia untuk aplikasi latar depan. Saat mengikat layanan, perhatikan kapan dan berapa lama Anda menggunakan binding. Pastikan untuk melepaskan binding segera setelah tidak diperlukan.
Pemikatan umum dan praktik terbaik:
- Play Integrity API: Digunakan untuk memeriksa integritas
perangkat
- Memeriksa integritas perangkat setelah layar pemuatan dan sebelum pemutaran media
- Rilis referensi ke PlayIntegrity
StandardIntegrityManager
sebelum memutar konten.
- Library Layanan Penagihan Play: Digunakan untuk mengelola
langganan dan pembelian menggunakan Google Play
- Lakukan inisialisasi library setelah layar pemuatan, dan tangani semua pekerjaan penagihan sebelum memutar media apa pun.
- Gunakan
BillingClient.endConnection()
setelah selesai menggunakan library dan selalu sebelum memutar video atau media. - Gunakan
BillingClient.isReady()
danBillingClient.getConnectionState()
untuk memeriksa apakah layanan terputus jika ada pekerjaan penagihan yang perlu dilakukan lagi, lalu lakukanBillingClient.endConnection()
lagi setelah selesai.
- GMS FontsProvider
- Sebaiknya gunakan font mandiri di perangkat dengan RAM rendah, bukan menggunakan penyedia font, karena mendownload font akan mahal dan FontsProvider akan mengikat layanan untuk melakukannya.
- Library Asisten Google: Terkadang
digunakan untuk penelusuran dan penelusuran dalam aplikasi. Jika memungkinkan, ganti library ini.
- Untuk aplikasi leanback: Gunakan teks ke ucapan Gboard atau
library androidx.leanback.
- Ikuti Panduan penelusuran untuk menerapkan penelusuran.
- Catatan: leanback tidak digunakan lagi dan aplikasi harus beralih ke TV Compose.
- Untuk aplikasi Compose:
- Gunakan teks ke ucapan Gboard untuk menerapkan penelusuran suara.
- Terapkan Tonton Berikutnya untuk membuat konten media di aplikasi Anda dapat ditemukan.
- Untuk aplikasi leanback: Gunakan teks ke ucapan Gboard atau
library androidx.leanback.
Layanan Latar Depan
Layanan Latar Depan adalah jenis layanan khusus yang terikat dengan notifikasi. Notifikasi ini ditampilkan di baki notifikasi di ponsel dan tablet, tetapi perangkat TV tidak memiliki baki notifikasi dalam arti yang sama seperti perangkat tersebut. Meskipun Layanan Latar Depan berguna karena dapat terus berjalan saat aplikasi berada di latar belakang, aplikasi TV harus mengikuti panduan berikut:
Di Android TV dan Google TV, Layanan Latar Depan hanya diizinkan untuk terus berjalan setelah pengguna keluar dari aplikasi:
- Untuk aplikasi audio: Layanan Latar Depan hanya diizinkan untuk terus berjalan setelah pengguna keluar dari aplikasi untuk terus memutar trek audio. Layanan harus segera dihentikan setelah pemutaran audio berakhir.
- Untuk aplikasi lain: semua Layanan Latar Depan harus dihentikan setelah pengguna keluar dari aplikasi Anda, karena tidak ada notifikasi untuk memberi tahu pengguna bahwa aplikasi masih berjalan dan menggunakan resource.
- Untuk tugas latar belakang seperti memperbarui rekomendasi atau
Tonton Berikutnya, gunakan
WorkManager
.
Tugas dan Alarm
WorkManager
adalah Android API canggih untuk menjadwalkan tugas berulang di latar belakang.
WorkManager akan menggunakan
JobScheduler
baru jika tersedia (SDK
23+) dan AlarmManager
lama jika
tidak. Untuk praktik terbaik dalam menjalankan tugas terjadwal di TV, ikuti rekomendasi
berikut:
- Hindari penggunaan API
AlarmManager
, pada SDK 23+, terutamaAlarmManager.set()
,AlarmManager.setExact()
, dan metode serupa, karena tidak memungkinkan sistem menentukan waktu yang tepat untuk menjalankan tugas (misalnya, saat perangkat tidak ada aktivitas). - Di perangkat dengan RAM rendah, hindari menjalankan tugas kecuali jika benar-benar diperlukan. Jika diperlukan,
gunakan WorkManager
WorkRequest
hanya untuk memperbarui rekomendasi setelah pemutaran, dan coba lakukan saat aplikasi masih terbuka. - Tentukan
Constraints
WorkManager agar sistem menjalankan tugas Anda pada waktu yang tepat:
Kotlin
Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresStorageNotLow(true) .setRequiresDeviceIdle(true) .build()
Java
Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresStorageNotLow(true) .setRequiresDeviceIdle(true) .build()
- Jika Anda harus menjalankan tugas secara rutin (misalnya, untuk memperbarui Tonton Berikutnya berdasarkan aktivitas menonton konten pengguna di aplikasi Anda di perangkat lain), pertahankan penggunaan memori agar tetap rendah dengan menjaga konsumsi memori tugas di bawah 30 MB.
Panduan umum lainnya
Pedoman berikut memberikan informasi umum tentang pengembangan Aplikasi Android:
- Minimalkan alokasi objek, optimalkan penggunaan kembali objek, dan batalkan alokasi objek
yang tidak digunakan dengan segera.
- Jangan menyimpan referensi ke objek, terutama bitmap.
- Hindari penggunaan
System.gc()
dan panggilan memori rilis langsung karena mengganggu proses penanganan memori sistem: Sebagai contoh, di perangkat yang menggunakan zRAM, panggilan paksa kegc()
dapat meningkatkan penggunaan memori untuk sementara karena kompresi dan dekompresi memori. - Gunakan
LazyList
seperti yang ditunjukkan dalam browser katalog di Compose atauRecyclerView
di toolkit UI Leanback yang kini tidak digunakan lagi untuk menggunakan kembali tampilan dan tidak membuat ulang elemen daftar. - Menyimpan elemen secara lokal yang dibaca dari penyedia konten eksternal yang tidak mungkin berubah dan menentukan interval pembaruan yang mencegah alokasi memori eksternal tambahan.
- Periksa kemungkinan kebocoran memori.
- Waspadai kasus kebocoran memori umum seperti referensi di dalam thread anonim, realokasi buffer video yang tidak pernah dirilis, dan situasi serupa lainnya.
- Gunakan heap dump untuk men-debug kebocoran memori.
- Buat profil dasar pengukuran untuk meminimalkan jumlah kompilasi tepat waktu yang diperlukan saat menjalankan aplikasi pada cold start.
Ringkasan alat
- Gunakan alat profiler memori Android Studio
untuk memeriksa konsumsi memori selama penggunaan.
- Gunakan heapdump untuk memeriksa alokasi bitmap dan objek tertentu.
- Gunakan profiler memori native untuk memeriksa alokasi non-Java atau Kotlin.
- Gunakan Android GPU Inspector untuk memeriksa alokasi grafis.