TransactionTooLargeException from rememberSaveable exceeding Bundle parcel limit
0 reputation · 10 Dec 2021, 13:19 UTC
0 reputation · 10 Dec 2021, 13:19 UTC
Determine whether Jetpack Compose should expose a runtime budget API or compile-time guard for rememberSaveable to prevent TransactionTooLargeException when saved state surpasses the platform's IPC parcel limit.
The Activity savedInstanceState Bundle enforces a ~50–100 KB parcel budget that varies by Android version and OEM. A single oversized rememberSaveable entry — such as a Room entity list, bitmap, or deep nested data class — can trigger android.os.TransactionTooLargeException at save time or silently truncate on some API levels, leaving the entire component tree with defaulted state on restore. Compose currently provides no API to inspect the serialized size of saved state at runtime, nor does it warn when a custom Saver produces a Parcelable payload that exceeds the budget. The platform limit is opaque to app code, and testing on emulators often fails to reproduce low-memory process kills.
rememberSaveable key's static type suggests a high risk of exceeding the parcel budget?SavedStateRegistry#getSavedStateSize()–style API feasible without introducing IPC overhead during normal operation?rememberSaveable entries across multiple Bundle keys violate restoration atomicity guarantees?35275 reputation · 10 Dec 2021, 15:29 UTC
rememberSaveable key whose type suggests a high risk of exceeding the parcel budget (e.g., collections, bitmaps, or large data classes). A compile‑time check is the most reliable guard because the exact size is only known after serialization and the platform limit is opaque to app code.Bundle size is technically feasible, but it would add overhead to every state change and still cannot guarantee compliance with every OEM’s IPC buffer limit. It is more practical to rely on compile‑time lint and developer‑side size checks.rememberSaveable entry into multiple Bundle keys would break the atomic restoration guarantee. After a process kill, the entries could be restored in an inconsistent order, leading to a corrupted state tree.The rememberSaveable value is marshalled into a Bundle that is later written to a Binder transaction. The Binder buffer is typically limited to roughly 50–100 KB, but the exact value varies by API level and OEM. Because the size is only determinable after the value has been marshalled, a compile‑time lint rule that flags potentially large types can catch many problems early. Runtime size checks would need to serialize the data on every state change, which is expensive and still cannot guarantee that the final IPC buffer will not be exceeded.
Parcelable objects. If you need to persist a large list, store it in a ViewModel or a database and only keep an identifier in rememberSaveable.Saver that trims or compresses data. For example, convert a bitmap to a compressed ByteArray and store the array size. Verify the size by marshalling the object into a Parcel and checking Parcel.dataSize() in a unit test.StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedClosableObjects().build()); in debug builds to catch large Bundle writes.savedInstanceState right before onSaveInstanceState:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val sizeBytes = Parcel.obtain().apply {
writeBundle(outState)
dataSize()
}
Log.d("SaveState", "sizeBytes=$sizeBytes")
}
rememberSaveable.To refine the recommendation, could you share the approximate byte size of the data you are currently saving with rememberSaveable and the target API level/OEM you are deploying to?
Lint is the most efficient way to flag high‑risk rememberSaveable usages. A lightweight runtime size query can help in debugging, but it cannot replace compile‑time safety. Splitting entries is discouraged because it breaks restoration atomicity. By trimming data, using custom savers, and testing on real devices, you can keep state restoration within the Binder IPC budget and avoid TransactionTooLargeException.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.