Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec9aea29 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Do not reuse fragment indices."

parents 487b2e3d 838166d3
Loading
Loading
Loading
Loading
+54 −57
Original line number Diff line number Diff line
@@ -552,6 +552,7 @@ final class FragmentManagerState implements Parcelable {
    int[] mAdded;
    BackStackState[] mBackStack;
    int mPrimaryNavActiveIndex = -1;
    int mNextFragmentIndex;
    
    public FragmentManagerState() {
    }
@@ -561,6 +562,7 @@ final class FragmentManagerState implements Parcelable {
        mAdded = in.createIntArray();
        mBackStack = in.createTypedArray(BackStackState.CREATOR);
        mPrimaryNavActiveIndex = in.readInt();
        mNextFragmentIndex = in.readInt();
    }
    
    public int describeContents() {
@@ -572,6 +574,7 @@ final class FragmentManagerState implements Parcelable {
        dest.writeIntArray(mAdded);
        dest.writeTypedArray(mBackStack, flags);
        dest.writeInt(mPrimaryNavActiveIndex);
        dest.writeInt(mNextFragmentIndex);
    }
    
    public static final Parcelable.Creator<FragmentManagerState> CREATOR
@@ -639,9 +642,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
    ArrayList<OpGenerator> mPendingActions;
    boolean mExecutingActions;

    ArrayList<Fragment> mActive;
    int mNextFragmentIndex = 0;
    SparseArray<Fragment> mActive;
    ArrayList<Fragment> mAdded;
    ArrayList<Integer> mAvailIndices;
    ArrayList<BackStackRecord> mBackStack;
    ArrayList<Fragment> mCreatedMenus;
    
@@ -839,6 +842,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        }

        doPendingDeferredStart();
        burpActive();
        return executePop;
    }

@@ -882,10 +886,6 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        if (index == -1) {
            return null;
        }
        if (index >= mActive.size()) {
            throwException(new IllegalStateException("Fragment no longer exists for key "
                    + key + ": index " + index));
        }
        Fragment f = mActive.get(index);
        if (f == null) {
            throwException(new IllegalStateException("Fragment no longer exists for key "
@@ -939,7 +939,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                        writer.print(Integer.toHexString(System.identityHashCode(this)));
                        writer.println(":");
                for (int i=0; i<N; i++) {
                    Fragment f = mActive.get(i);
                    Fragment f = mActive.valueAt(i);
                    writer.print(prefix); writer.print("  #"); writer.print(i);
                            writer.print(": "); writer.println(f);
                    if (f != null) {
@@ -1034,10 +1034,6 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
            writer.print(prefix); writer.print("  mNoTransactionsBecause=");
                    writer.println(mNoTransactionsBecause);
        }
        if (mAvailIndices != null && mAvailIndices.size() > 0) {
            writer.print(prefix); writer.print("  mAvailIndices: ");
                    writer.println(Arrays.toString(mAvailIndices.toArray()));
        }
    }

    Animator loadAnimator(Fragment fragment, int transit, boolean enter,
@@ -1164,7 +1160,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                        // If we have a target fragment, push it along to at least CREATED
                        // so that this one can rely on it as an initialized dependency.
                        if (f.mTarget != null) {
                            if (!mActive.contains(f.mTarget)) {
                            if (mActive.get(f.mTarget.mIndex) != f.mTarget) {
                                throw new IllegalStateException("Fragment " + f
                                        + " declared target fragment " + f.mTarget
                                        + " that does not belong to this FragmentManager!");
@@ -1557,7 +1553,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
            // and detached.
            final int numActive = mActive.size();
            for (int i = 0; i < numActive; i++) {
                Fragment f = mActive.get(i);
                Fragment f = mActive.valueAt(i);
                if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
                    moveFragmentToExpectedState(f);
                    if (f.mLoaderManager != null) {
@@ -1581,7 +1577,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        if (mActive == null) return;

        for (int i=0; i<mActive.size(); i++) {
            Fragment f = mActive.get(i);
            Fragment f = mActive.valueAt(i);
            if (f != null) {
                performPendingDeferredStart(f);
            }
@@ -1593,17 +1589,11 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
            return;
        }

        if (mAvailIndices == null || mAvailIndices.size() <= 0) {
        f.setIndex(mNextFragmentIndex++, mParent);
        if (mActive == null) {
                mActive = new ArrayList<Fragment>();
            }
            f.setIndex(mActive.size(), mParent);
            mActive.add(f);
            
        } else {
            f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
            mActive.set(f.mIndex, f);
            mActive = new SparseArray<>();
        }
        mActive.put(f.mIndex, f);
        if (DEBUG) Log.v(TAG, "Allocated fragment index " + f);
    }
    
@@ -1613,11 +1603,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        }
        
        if (DEBUG) Log.v(TAG, "Freeing fragment index " + f);
        mActive.set(f.mIndex, null);
        if (mAvailIndices == null) {
            mAvailIndices = new ArrayList<Integer>();
        }
        mAvailIndices.add(f.mIndex);
        // Don't remove yet. That happens in burpActive(). This prevents
        // concurrent modification while iterating over mActive
        mActive.put(f.mIndex, null);
        mHost.inactivateFragment(f.mWho);
        f.initState();
    }
@@ -1754,7 +1742,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        if (mActive != null) {
            // Now for any known fragment.
            for (int i=mActive.size()-1; i>=0; i--) {
                Fragment f = mActive.get(i);
                Fragment f = mActive.valueAt(i);
                if (f != null && f.mFragmentId == id) {
                    return f;
                }
@@ -1776,7 +1764,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        if (mActive != null && tag != null) {
            // Now for any known fragment.
            for (int i=mActive.size()-1; i>=0; i--) {
                Fragment f = mActive.get(i);
                Fragment f = mActive.valueAt(i);
                if (f != null && tag.equals(f.mTag)) {
                    return f;
                }
@@ -1788,7 +1776,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
    public Fragment findFragmentByWho(String who) {
        if (mActive != null && who != null) {
            for (int i=mActive.size()-1; i>=0; i--) {
                Fragment f = mActive.get(i);
                Fragment f = mActive.valueAt(i);
                if (f != null && (f=f.findFragmentByWho(who)) != null) {
                    return f;
                }
@@ -1953,6 +1941,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        }

        doPendingDeferredStart();
        burpActive();
    }

    /**
@@ -1983,6 +1972,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        }

        doPendingDeferredStart();
        burpActive();

        return didSomething;
    }
@@ -2248,7 +2238,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
            for (int i = 0; i < numActive; i++) {
                // Allow added fragments to be removed during the pop since we aren't going
                // to move them to the final state with moveToState(mCurState).
                Fragment fragment = mActive.get(i);
                Fragment fragment = mActive.valueAt(i);
                if (fragment != null && fragment.mView != null && fragment.mIsNewlyAdded
                        && record.interactsWith(fragment.mContainerId)) {
                    fragment.mIsNewlyAdded = false;
@@ -2360,7 +2350,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
    private void endAnimatingAwayFragments() {
        final int numFragments = mActive == null ? 0 : mActive.size();
        for (int i = 0; i < numFragments; i++) {
            Fragment fragment = mActive.get(i);
            Fragment fragment = mActive.valueAt(i);
            if (fragment != null && fragment.getAnimatingAway() != null) {
                // Give up waiting for the animation and just end it.
                fragment.getAnimatingAway().end();
@@ -2400,7 +2390,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        if (mHavePendingDeferredStart) {
            boolean loadersRunning = false;
            for (int i=0; i<mActive.size(); i++) {
                Fragment f = mActive.get(i);
                Fragment f = mActive.valueAt(i);
                if (f != null && f.mLoaderManager != null) {
                    loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                }
@@ -2489,7 +2479,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        ArrayList<FragmentManagerNonConfig> childFragments = null;
        if (mActive != null) {
            for (int i=0; i<mActive.size(); i++) {
                Fragment f = mActive.get(i);
                Fragment f = mActive.valueAt(i);
                if (f != null) {
                    if (f.mRetainInstance) {
                        if (fragments == null) {
@@ -2594,7 +2584,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        FragmentState[] active = new FragmentState[N];
        boolean haveFragments = false;
        for (int i=0; i<N; i++) {
            Fragment f = mActive.get(i);
            Fragment f = mActive.valueAt(i);
            if (f != null) {
                if (f.mIndex < 0) {
                    throwException(new IllegalStateException(
@@ -2680,6 +2670,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        fms.mActive = active;
        fms.mAdded = added;
        fms.mBackStack = backStack;
        fms.mNextFragmentIndex = mNextFragmentIndex;
        if (mPrimaryNav != null) {
            fms.mPrimaryNavActiveIndex = mPrimaryNav.mIndex;
        }
@@ -2722,10 +2713,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        
        // Build the full list of active fragments, instantiating them from
        // their saved state.
        mActive = new ArrayList<>(fms.mActive.length);
        if (mAvailIndices != null) {
            mAvailIndices.clear();
        }
        mActive = new SparseArray<>(fms.mActive.length);
        for (int i=0; i<fms.mActive.length; i++) {
            FragmentState fs = fms.mActive[i];
            if (fs != null) {
@@ -2735,18 +2723,11 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                }
                Fragment f = fs.instantiate(mHost, mContainer, mParent, childNonConfig);
                if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f);
                mActive.add(f);
                mActive.put(f.mIndex, f);
                // Now that the fragment is instantiated (or came from being
                // retained above), clear mInstance in case we end up re-restoring
                // from this FragmentState again.
                fs.mInstance = null;
            } else {
                mActive.add(null);
                if (mAvailIndices == null) {
                    mAvailIndices = new ArrayList<>();
                }
                if (DEBUG) Log.v(TAG, "restoreAllState: avail #" + i);
                mAvailIndices.add(i);
            }
        }
        
@@ -2757,9 +2738,8 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
            for (int i = 0; i < count; i++) {
                Fragment f = nonConfigFragments.get(i);
                if (f.mTargetIndex >= 0) {
                    if (f.mTargetIndex < mActive.size()) {
                    f.mTarget = mActive.get(f.mTargetIndex);
                    } else {
                    if (f.mTarget == null) {
                        Log.w(TAG, "Re-attaching retained fragment " + f
                                + " target no longer exists: " + f.mTargetIndex);
                        f.mTarget = null;
@@ -2813,6 +2793,23 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        if (fms.mPrimaryNavActiveIndex >= 0) {
            mPrimaryNav = mActive.get(fms.mPrimaryNavActiveIndex);
        }

        mNextFragmentIndex = fms.mNextFragmentIndex;
    }

    /**
     * To prevent list modification errors, mActive sets values to null instead of
     * removing them when the Fragment becomes inactive. This cleans up the list at the
     * end of executing the transactions.
     */
    private void burpActive() {
        if (mActive != null) {
            for (int i = mActive.size() - 1; i >= 0; i--) {
                if (mActive.valueAt(i) == null) {
                    mActive.delete(mActive.keyAt(i));
                }
            }
        }
    }

    public void attachController(FragmentHostCallback<?> host, FragmentContainer container,
@@ -3051,8 +3048,8 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
    }

    public void setPrimaryNavigationFragment(Fragment f) {
        if (f != null && (f.getFragmentManager() != this || f.mIndex >= mActive.size()
                || mActive.get(f.mIndex) != f)) {
        if (f != null && (mActive.get(f.mIndex) != f
                || (f.mHost != null && f.getFragmentManager() != this))) {
            throw new IllegalArgumentException("Fragment " + f
                    + " is not an active fragment of FragmentManager " + this);
        }