Android Development
TransactionTooLargeException
Exception Handling
Android Errors
App Development Tips

What to do on TransactionTooLargeException

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

TransactionTooLargeException usually means an Android process tried to send too much data through Binder. The fix is rarely to catch the exception and continue. The real solution is to shrink what crosses process or activity boundaries and move large state into storage, repositories, or in-memory components.

Why the Exception Happens

Android uses Binder for inter-process and many framework-managed transactions. Extras in an Intent, fragment arguments, saved instance state, and some service calls all contribute to the same transaction mechanism.

The practical limit is around 1 MB for a Binder transaction, including metadata, but code should not treat that as safe headroom. Multiple objects, nested Bundle values, and parceling overhead can push an apparently small payload over the limit.

Common triggers include:

  • passing a large list of parcelables between activities
  • saving a huge screen state in onSaveInstanceState
  • putting Bitmap data directly into a Bundle
  • returning oversized results from a service or another activity

Pass Identifiers, Not Full Objects

The most reliable pattern is to pass a lightweight key and let the receiving screen load the full data from a repository, database, or file.

kotlin
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("article_id", article.id)
startActivity(intent)

Then resolve the content inside the destination:

kotlin
1class DetailViewModel(
2    private val repository: ArticleRepository,
3    savedStateHandle: SavedStateHandle
4) : ViewModel() {
5
6    private val articleId: Long = checkNotNull(savedStateHandle["article_id"])
7    val article = repository.observeArticle(articleId)
8}

This approach scales much better than parceling an entire object graph every time the user navigates.

Do Not Put Large Binary Data in Bundles

Images are a frequent cause of this exception. Instead of passing a bitmap, write the file once and pass a Uri or path reference.

kotlin
1val photoUri: Uri = savedPhotoUri()
2val intent = Intent(this, PreviewActivity::class.java)
3intent.putExtra("photo_uri", photoUri.toString())
4startActivity(intent)

In the receiving activity:

kotlin
val photoUri = Uri.parse(intent.getStringExtra("photo_uri"))
imageView.setImageURI(photoUri)

The transaction now carries a tiny string instead of megabytes of pixel data.

Watch onSaveInstanceState

Many crashes happen during backgrounding or rotation because developers store too much transient UI state in the saved instance bundle. Save only what is required to reconstruct the screen, such as IDs, filter settings, or scroll positions.

Bad candidates for saved state include cached network responses, long text blobs that already exist elsewhere, and view model data that can be reloaded.

If state must survive configuration changes but not process death, a ViewModel is often a better container than a Bundle.

Service and IPC Boundaries Need the Same Discipline

If a bound service, broadcast, or result callback returns too much data, apply the same rule: return a handle, not the full payload. For large documents or media, use files, a database row, or a content provider.

This pattern also improves versioning. A stable ID or Uri is easier to evolve than a large parcelable contract shared across components.

A Small Refactor Pattern

Suppose an activity currently sends a full order object.

kotlin
1data class Order(
2    val id: Long,
3    val customerName: String,
4    val items: List<OrderItem>,
5    val notes: String,
6    val imageBytes: ByteArray
7) : Parcelable

That payload is risky. A safer contract sends only the order ID:

kotlin
intent.putExtra("order_id", order.id)

The destination screen then loads the order from Room or another repository. This reduces transaction size, startup fragility, and parceling overhead.

Diagnose Before and After the Fix

If the crash is intermittent, inspect which extras and saved-state values are growing over time. Large lists and image fields are typical offenders. Reproducing with device rotation or repeated navigation is often enough to expose the issue.

After refactoring, verify that no heavy objects remain in fragment arguments, activity results, or saved state bundles. The goal is structural: the app should no longer rely on Binder for large payload transport.

Common Pitfalls

A common mistake is wrapping the call in try and assuming the app is now safe. The transaction may still fail later when the framework saves state.

Another pitfall is storing everything in onSaveInstanceState because it feels convenient. Bundles are for small reconstruction hints, not full screen caches.

Developers also underestimate parcel overhead. A list of parcelables can exceed the Binder limit long before its raw field sizes seem dangerous.

Summary

  • 'TransactionTooLargeException is usually a Binder payload design problem.'
  • Pass IDs, keys, or Uri values instead of large objects or bitmaps.
  • Keep onSaveInstanceState small and focused on reconstruction state.
  • Use repositories, files, databases, or content providers for heavy data.
  • Fixing the data flow is more reliable than catching the exception.

Course illustration
Course illustration

All Rights Reserved.