Here is some background to help anyone who encounters this exception.
The exception is thrown because the framework doesn't allow to commit a fragment transaction in the same call stack as onLoadFinished().This behavior provides a protection against state lose, because loaders are normally based on background threads (AsyncTaskLoader) which can finish their work and notify back anytime.
There could be two potential issues:1. The framework already saved the state (for example because of orientation change) of the fragments in the fragment manager when the call to onLoadFinished() is performed.Committing a transaction in this context will result in state lose because this late transaction is not included in the saved state.2. The framework has not finished restoring from a previous saved state.Here, the transaction comes too early before the state has been restored.
There are two problems with Maria's answer above:1. calling runOnUiThread() doesn't help because onLoadFinished() is called on the UI thread which means the call to runOnUiThread() will be called in the same call stack which will raise the exception.The documentation says: "If the current thread is the UI thread, then the action is executed immediately."2. Even if the call (here DialogFragment.show()) hadn't been done in the same call stack) for example by:
public void onLoadFinished(Loader<Map<String, Integer>> arg0, Map<String, Integer> result) { if (result == null) { new Handler().post(new Runnable() { @Override public void run() { netEMessage(); } }); } }
the risks above would still exist.
The best solution to this issue is to move the fragment transaction to a different place in the flow while ensuring issues 1. and 2. above cannot happen. For example, performing the transaction from Activity.onPostResume().
Good luck!