Saat mengelola siklus proses aplikasi Android, mempertahankan status pengguna selama reklamasi resource latar belakang adalah komponen inti dari pengalaman pengguna yang lancar. Untuk aplikasi yang menggabungkan alur kerja web, WebView.saveState(Bundle)
memungkinkan Anda membuat serialisasi histori navigasi dan status WebView ke dalam Bundle.
Data ini selanjutnya dapat dipulihkan menggunakan WebView.restoreState(Bundle).
Namun, penerapan standar dapat mengalami batasan ukuran transaksi dalam sesi penjelajahan yang berat. Halaman ini menjelaskan batasan arsitektur ini dan memberikan strategi untuk mencegah pengecualian terkait memori sekaligus mempertahankan histori navigasi.
Batas transaksi 1 MB dan penghapusan status
Android memberlakukan batas ketat 1 MB pada total volume data yang dapat disimpan dalam savedInstanceState. Anggaran 1 MB ini digunakan bersama di seluruh proses aplikasi. Jika aplikasi menggabungkan beberapa instance WebView, status dan histori navigasi kolektifnya harus sesuai dengan alokasi bersama tunggal ini. Melebihi batas ini akan memicu TransactionTooLargeException, yang mengakibatkan aplikasi mengalami error.
Strategi mitigasi yang umum tetapi bermasalah melibatkan pemantauan ukuran paket status WebView dan menghapus sepenuhnya histori WebView jika melintasi batas keamanan arbitrer (seperti 300 KB). Meskipun hal ini mencegah error, hal ini menyebabkan regresi parah pada pengalaman pengguna:
Kehilangan navigasi mundur: Android sering menghentikan proses aplikasi latar belakang untuk mereklamasi memori untuk tugas lain. Anda dapat menggunakan
saveState(Bundle)dalam callback siklus prosesonSaveInstanceState()untuk mempertahankan histori navigasi. Jika Anda menghapus histori ini untuk menghindari batas transaksi 1 MB, seluruh tumpukan navigasi akan hilang. Saat pengguna kembali ke aplikasi, tombol kembali sistem akan segera keluar dari komponen atau aplikasi karena tidak ada konteks historis yang tersisa untuk mendukung navigasi mundur, terlepas dari apakah proses dimulai ulang atau tidak.Invalidasi BFCache: Menghapus histori akan mencegah aplikasi menggunakan Cache Kembali-Maju (BFCache), sehingga menghapus kemampuan untuk langsung merender halaman yang sebelumnya dikunjungi.
Peningkatan latensi: Pengguna kehilangan status saat ini dalam WebView, sehingga memerlukan navigasi ulang dan inisialisasi ulang sepenuhnya. Proses ini secara signifikan meningkatkan overhead jaringan dan latensi transaksi.
Strategi mitigasi arsitektur
Untuk mencegah TransactionTooLargeException error tanpa menurunkan kualitas
pengalaman pengguna melalui penghapusan histori lengkap, Anda harus mempertahankan keseimbangan yang ketat antara retensi status dan efisiensi memori. Dengan menerapkan strategi pengoptimalan berikut, Anda dapat mengelola anggaran transaksi 1 MB dengan aman sekaligus mempertahankan histori navigasi penting dan integritas sesi.
Menerapkan batas ukuran pada serialisasi status
Daripada menghapus sepenuhnya tumpukan navigasi saat ukurannya terlalu besar, pola yang lebih efektif adalah memangkas data historis:
Kebijakan penghapusan yang ditargetkan: Gunakan
WebViewCompat.saveState()untuk membuat serialisasi status sekaligus menerapkan batas byte tertentu (misalnya,WebViewCompat.saveState(webView, outState, maxSizeBytes)). API ini secara otomatis menghapus entri navigasi lama secara berurutan hingga total payload sesuai dengan alokasi yang Anda tentukan. Yang terpenting, hal ini hanya memangkasBundleyang diserialisasi tanpa mengubah atau menghapus histori aktifWebView, sehingga memastikan navigasi mundur langsung tetap utuh.Penghapusan entri maju: Jika antarmuka aplikasi menyediakan tombol kembali tetapi tidak memiliki tombol navigasi maju khusus, Anda dapat menghapus semua entri navigasi maju dengan menetapkan parameter
includeForwardStatesaveStateAPI kefalse. Hal ini secara signifikan mengurangi ukuran payload tanpa memengaruhi jalur navigasi yang tersedia bagi pengguna.
Mengelola latensi resource dengan HTTP Cache Quota API
Meskipun saveState mengelola batas Bundle 1 MB untuk histori navigasi sementara, HTTP Cache Quota API memberikan kontrol manual atas resource web yang dipertahankan (cache disk) berdasarkan per profil. Hal ini menciptakan perbedaan yang jelas antara konteks navigasi jangka pendek dan aset yang di-cache jangka panjang.
Memilih kuota yang sesuai melibatkan pertukaran performa:
- Kuota yang lebih tinggi meningkatkan ketersediaan offline dan latensi pemuatan resource dengan menyimpan lebih banyak aset di disk.
- Kuota yang lebih rendah meminimalkan jejak disk aplikasi dan mencegah penghapusan cache yang dipimpin OS dari data aplikasi penting lainnya.
Setelan ini dipertahankan di seluruh proses aplikasi dimulai ulang dan harus dikonfigurasi dari thread utama.
Implementasi berikut menunjukkan cara mengonfigurasi kuota cache disk untuk profil default:
Kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.MULTI_PROFILE) &&
WebViewFeature.isFeatureSupported(WebViewFeature.HTTP_CACHE)) {
val defaultProfile = ProfileStore.getInstance()
.getOrCreateProfile(Profile.DEFAULT_PROFILE_NAME)
val httpCache = defaultProfile.httpCache
// Set explicit cache size to 50MB (50 * 1024 * 1024 bytes)
httpCache.setQuotaBytes(50L * 1024 * 1024)
}
Java
if (WebViewFeature.isFeatureSupported(WebViewFeature.MULTI_PROFILE) &&
WebViewFeature.isFeatureSupported(WebViewFeature.HTTP_CACHE)) {
Profile defaultProfile = ProfileStore.getInstance()
.getOrCreateProfile(Profile.DEFAULT_PROFILE_NAME);
HttpCache httpCache = defaultProfile.getHttpCache();
// Set explicit cache size to 50MB (50 * 1024 * 1024 bytes)
httpCache.setQuotaBytes(50L * 1024 * 1024);
}
Untuk mengetahui informasi selengkapnya tentang strategi ukuran kuota, pengelolaan siklus proses, dan batas profil, lihat Mengelola kuota cache HTTP di WebView.
Pertimbangan performa utama
Poin-poin berikut menyoroti batasan teknis dan perilaku data internal yang mengatur perilaku status WebView:
Blob
PageStateburam: Sekitar 70% data yang disimpan olehsaveStateterdiri dari blobPageStateinternal dari mesin rendering. Data ini menangkap status sesi terperinci, termasuk input formulir dan posisi scroll iframe. Hindari mencoba mengurai atau menghapus segmen individual dari blob ini secara manual, karena tindakan tersebut menimbulkan risiko keamanan yang parah dan merusak integritas pemulihan sesi.Pengelolaan histori terperinci: API standar
WebBackForwardListtidak secara native mendukung penghapusan arbitrer elemen historis individual. Untuk pengelolaan status yang ketat, Anda harus menerapkan strategi pemangkasan menggunakan parametermaxSizeBytesdanincludeForwardStatedalamWebViewCompat.saveState()untuk memastikan keamanan arsitektur.