Skip to content

Instantly share code, notes, and snippets.

@rayworks
Created February 26, 2018 09:04
Show Gist options
  • Save rayworks/5e3ab37899bcee166cf2775c6d8aa19c to your computer and use it in GitHub Desktop.
Save rayworks/5e3ab37899bcee166cf2775c6d8aa19c to your computer and use it in GitHub Desktop.
Get rid of IllegalStateException when comitting the fragment transaction after the activity’s state had been saved
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import java.util.LinkedList;
import timber.log.Timber;
/**
* A non-UI related Fragment as a state persistence monitor.
*
* <p>https://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html
*/
public class PlaceHolderFragment extends Fragment {
public static final String TAG = "EF_PlaceHolderFragment";
private LinkedList<UiRunnable> taskBuffer = new LinkedList<>();
private FragmentActivity host;
public PlaceHolderFragment() {
// Required empty public constructor
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// just bounded
host = getActivity();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onResume() {
super.onResume();
playback();
}
/**
* * Executes Fragment related operation safely.
*
* @param runnable {@link UiRunnable}
*/
public void tryWithAction(UiRunnable runnable) {
if (host != null) {
final FragmentManager fragmentManager = host.getSupportFragmentManager();
if (fragmentManager.isStateSaved()) {
Timber.i("<<< app state persisted already, delay the action.");
collect(runnable);
} else {
runnable.run(host);
}
} else {
collect(runnable);
}
}
private void playback() {
while (!taskBuffer.isEmpty()) {
Timber.i("<<< replay the action now");
UiRunnable runnable = taskBuffer.pop();
runnable.run(host);
}
}
private void collect(UiRunnable runnable) {
Timber.i("<<< collect the action %s", runnable);
taskBuffer.add(runnable);
}
@Override
public void onDestroy() {
super.onDestroy();
host = null;
}
public interface UiRunnable {
/**
* * Executes the task with current bounded {@link FragmentActivity}
*
* @param activity
*/
void run(FragmentActivity activity);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment