How to Fix Android Fragment Transaction Error
In this tutorial, you'll learn about How to Fix Android Fragment Transaction Error. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
The Problem
Your app crashes during a fragment Transaction:
java.lang.IllegalStateException: Can not perform this action
after onSaveInstanceState
Or:
FragmentManager is already executing transactions
Fragment transactions fail when they are attempted at an illegal point in the Activity lifecycle, particularly after onSaveInstanceState.
Quick Fix
Step 1: Use commitAllowingStateLoss when appropriate
// May throw in some cases
supportFragmentManager.beginTransaction()
.replace(R.id.container, MyFragment())
.commit()
// Safe after onSaveInstanceState
supportFragmentManager.beginTransaction()
.replace(R.id.container, MyFragment())
.commitAllowingStateLoss()
Use commitAllowingStateLoss when the Transaction result does not affect persisted state (e.g., dismissing a dialog).
Step 2: Use commitNow instead of commit
// Execute synchronously instead of asynchronously
supportFragmentManager.beginTransaction()
.replace(R.id.container, MyFragment())
.commitNow()
commitNow executes immediately and avoids timing issues with executePendingTransactions.
Step 3: Check the fragment manager lifecycle
if (isAdded && supportFragmentManager != null && !supportFragmentManager.isStateSaved) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MyFragment())
.commit()
}
Guard every Transaction with a lifecycle check.
Step 4: Avoid transactions in async callbacks
// Wrong - may trigger after onSaveInstanceState
viewModel.data.observe(this) { data ->
supportFragmentManager.beginTransaction().replace(R.id.container, FragmentB()).commit()
}
// Right - check state before committing
viewModel.data.observe(this) { data ->
if (!supportFragmentManager.isStateSaved) {
supportFragmentManager.beginTransaction().replace(R.id.container, FragmentB()).commit()
}
}
Step 5: Use the correct fragment manager
| Context | Manager |
|---|---|
| Activity | supportFragmentManager |
| Fragment | childFragmentManager |
| Nested fragment | childFragmentManager |
Mixing managers (calling parentFragmentManager from a parent instead of childFragmentManager) can cause inconsistent back stack behavior.
Step 6: Add to back stack correctly
supportFragmentManager.beginTransaction()
.replace(R.id.container, FragmentA())
.addToBackStack("fragment_a")
.commit()
Without addToBackStack, pressing Back exits the Activity instead of returning to the previous fragment.
Prevention
- Always check
isStateSavedbefore committing transactions from callbacks. - Use
commitNowfor immediate, non-queued transactions. - Prefer
commitAllowingStateLossfor non-critical UI updates.
Common Mistakes with fragment Transaction
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists - Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad
These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
DodaTech Tool Reference
Doda Browser's Fragment Inspector (available in Developer Tools) visualizes the current fragment back stack and Transaction queue, helping debug state-loss crashes during development.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro