From 687e5500421b4d99f864bebfed6c573dc4f38191 Mon Sep 17 00:00:00 2001 From: George Mount Date: Wed, 2 Nov 2016 14:33:18 -0700 Subject: [PATCH] Don't update fragments if the manager's state doesn't change. Bug 32610133 A change in behavior was introduced in which the dispatch* methods moved the state of the manager's fragments even when the manager's state doesn't change. Test: I88f5a3313ad05429167c417b840f888f86fd1c11 Change-Id: Ie260b1c57fae505b2636ff7572a493a92449dff4 --- core/java/android/app/BackStackRecord.java | 4 +-- core/java/android/app/FragmentManager.java | 35 +++++++++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index cf794c5b410ee..42a2f19503b64 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -762,7 +762,7 @@ final class BackStackRecord extends FragmentTransaction implements } if (!mAllowOptimization) { // Added fragments are added at the end to comply with prior behavior. - mManager.moveToState(mManager.mCurState); + mManager.moveToState(mManager.mCurState, true); } } @@ -808,7 +808,7 @@ final class BackStackRecord extends FragmentTransaction implements } } if (!mAllowOptimization) { - mManager.moveToState(mManager.mCurState); + mManager.moveToState(mManager.mCurState, true); } } diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 5a2c5e771807c..07ef136e7ac51 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -1445,11 +1445,24 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate } } - void moveToState(int newState) { + /** + * Changes the state of the fragment manager to {@code newState}. If the fragment manager + * changes state or {@code always} is {@code true}, any fragments within it have their + * states updated as well. + * + * @param newState The new state for the fragment manager + * @param always If {@code true}, all fragments update their state, even + * if {@code newState} matches the current fragment manager's state. + */ + void moveToState(int newState, boolean always) { if (mHost == null && newState != Fragment.INITIALIZING) { throw new IllegalStateException("No activity"); } + if (!always && mCurState == newState) { + return; + } + mCurState = newState; if (mActive != null) { @@ -2024,7 +2037,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate // need to run something now FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, postponeIndex, true); - moveToState(mCurState); + moveToState(mCurState, true); } for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { @@ -2117,7 +2130,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true); } if (moveToState) { - moveToState(mCurState); + moveToState(mCurState, true); } else if (mActive != null) { final int numActive = mActive.size(); for (int i = 0; i < numActive; i++) { @@ -2691,40 +2704,40 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate public void dispatchCreate() { mStateSaved = false; - moveToState(Fragment.CREATED); + moveToState(Fragment.CREATED, false); } public void dispatchActivityCreated() { mStateSaved = false; - moveToState(Fragment.ACTIVITY_CREATED); + moveToState(Fragment.ACTIVITY_CREATED, false); } public void dispatchStart() { mStateSaved = false; - moveToState(Fragment.STARTED); + moveToState(Fragment.STARTED, false); } public void dispatchResume() { mStateSaved = false; - moveToState(Fragment.RESUMED); + moveToState(Fragment.RESUMED, false); } public void dispatchPause() { - moveToState(Fragment.STARTED); + moveToState(Fragment.STARTED, false); } public void dispatchStop() { - moveToState(Fragment.STOPPED); + moveToState(Fragment.STOPPED, false); } public void dispatchDestroyView() { - moveToState(Fragment.CREATED); + moveToState(Fragment.CREATED, false); } public void dispatchDestroy() { mDestroyed = true; execPendingActions(); - moveToState(Fragment.INITIALIZING); + moveToState(Fragment.INITIALIZING, false); mHost = null; mContainer = null; mParent = null;