commitAllowingStateLoss() in fragment activities

If I understand correctly you mean : Is there any reason NOT to indiscriminately do this without re-evaluating each individual case where I use a fragment?

The answer is Yes - you should not do this without carefully re-evaluating each individual case where you use a fragment.

Of course, by preventing restarts due to config changes (screen rotations) you have eliminated one of the key problem areas : i.e. the user could rotate the screen AFTER a call to onSaveInstanceState but BEFORE the commitAllowingStateLoss. In this case a fragment or portion of UI might be lost. For an informal discussion of this, see this post.

But there are other situations you should consider before replacing commit by commitAllowingStateLoss.

  1. Basically, any UI updates between onSaveInstanceState and the commitAllowingStateLoss: Android: IllegalStateException - When is it thrown?

  2. If you have any headless fragments that update the UI of your activity then some of their updates might be lost (see this article).

  3. Android might "kill" a fragment because the phone/tab is running low on resources (see this answer).

Of course, if screen rotations are prevented, then onSaveInstanceState may not be called, in which case the window of opportunity for an update to be lost is increased.

If you do decide to use commitAllowingStateLoss then are things you can do to minimize the risks involved: e.g. consider doing a commit / executePendingTransactions when the parent activity is next restarted (I know you don't want to do this, but someone else might read this).

Finally (again in case someone else reads this - this is not relevant in your case) there are probably safer ways of handling an IllegalStateException than moving from commit to commitAllowStateLoss. e.g you could just stick with commit and handle the IllegalStateException. Alternatively, you may have hit a bug in Android and there might be a workaround.


public abstract int commit ()

Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.

A transaction can only be committed with this method prior to its containing activity saving its state. If the commit is attempted after that point, an exception will be thrown. This is because the state after the commit can be lost if the activity needs to be restored from its state. See commitAllowingStateLoss() for situations where it may be okay to lose the commit.

public abstract int commitAllowingStateLoss ()

Added in API level 11

Like commit() but allows the commit to be executed after an activity's state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.

FragmentActivity limitations

Prior to Honeycomb (3.0), an activity's state was saved before pausing. Fragments are a significant amount of new state, and dynamic enough that one often wants them to change between pausing and stopping. These classes throw an exception if you try to change the fragment state after it has been saved, to avoid accidental loss of UI state. However this is too restrictive prior to Honeycomb, where the state is saved before pausing. To address this, when running on platforms prior to Honeycomb an exception will not be thrown if you change fragments between the state save and the activity being stopped. This means that in some cases if the activity is restored from its last saved state, this may be a snapshot slightly before what the user last saw.

So, if you're not concearned with the state loss, i think your decision is ok. i hope it helps you with your decision.


try {
    transaction.commit();
} catch (IllegalStateException e) {
}

A better idea would be using commit() in OnPostResume callbacks rather than using commitAllowingStateLoss() indiscriminately. Following blogpost provides a detailed explanantion http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

@Override
protected void onPostResume() {
    super.onPostResume();
    // Commit your transactions here.
}