Don't commit transactions after onSaveInstanceState()
- On the tablet portrait view, once the contact details are loaded,
a runnable is posted to a handler to properly setup the fragments
(by showing/hiding the ContactDetailFragment or ViewPager/Tab carousel)
- Since it's posted to a handler, we need to make sure that
onSaveInstanceState has not already been called or at least allow
the fragment transaction to be lost if it has been
- Prevent the runnable from doing anything if the activity is already
destroyed
Bug: 5011890
Change-Id: Ib43278f21eee390202ffe4b7ed4057482c34e61c
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 6d031e9..579c833 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -180,6 +180,14 @@
*/
private boolean mFragmentInitialized;
+ /**
+ * Whether or not the activity is destroyed. This flag is needed to ensure that the
+ * {@link Handler} does not execute any {@link FragmentTransaction}s in {@link Runnable}s
+ * after the activity is destroyed.
+ * TODO: Figure out a way to get rid of the {@link Handler} or make the operation safe.
+ */
+ private boolean mIsActivityDestroyed = false;
+
/** Sequential ID assigned to each instance; used for logging */
private final int mInstanceId;
private static final AtomicInteger sNextInstanceId = new AtomicInteger();
@@ -463,6 +471,7 @@
@Override
protected void onDestroy() {
+ mIsActivityDestroyed = true;
// mActionBarAdapter will be null here when redirecting to another activity in
// configureContentView().
if (mActionBarAdapter != null) {
@@ -1005,6 +1014,10 @@
mHandler.post(new Runnable() {
@Override
public void run() {
+ // Don't continue setting up the detail page if the activity is destroyed.
+ if (mIsActivityDestroyed) {
+ return;
+ }
if (!mContactDetailLayoutController.isInitialized()) {
mContactDetailLayoutController.setContactDetailFragment(
mContactDetailFragment);
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index 826d720..dda3884 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -161,7 +161,12 @@
throw new IllegalStateException("Invalid LayoutMode " + mLayoutMode);
}
- ft.commit();
+ // If the activity has already saved its state, then allow this fragment
+ // transaction to be dropped because there's nothing else we can do to update the UI.
+ // The fact that the contact URI has already been saved by the activity means we can
+ // restore this later.
+ // TODO: Figure out if this is really the solution we want.
+ ft.commitAllowingStateLoss();
}
private void showContactWithoutUpdates() {
@@ -182,7 +187,12 @@
throw new IllegalStateException("Invalid LayoutMode " + mLayoutMode);
}
- ft.commit();
+ // If the activity has already saved its state, then allow this fragment
+ // transaction to be dropped because there's nothing else we can do to update the UI.
+ // The fact that the contact URI has already been saved by the activity means we can
+ // restore this later.
+ // TODO: Figure out if this is really the solution we want.
+ ft.commitAllowingStateLoss();
}
public void onSaveInstanceState(Bundle outState) {