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

Commit 8585ed66 authored by Adam Powell's avatar Adam Powell
Browse files

FragmentTransaction.commitNow, framework edition

Offer commitNow and commitNowAllowingStateLoss methods on Fragment for
use by encapsulated components using fragments as implementation
details. This can help prevent unexpected ordering side effects at the
app level when a call to a library method wants to commit and
immediately initialize a fragment as an implementation detail.

Note that this change still does not permit reentrant FragmentManager
operations. It is still an error to add/remove/change fragments in the
same FragmentManager while a fragment transaction is being executed.

Have the commonly used ViewPager adapters use commitNow instead of
executePendingTransactions.

Change-Id: Ia37a871234a287423063f0c2c3e4c93d69116cad
(cherry picked from commit f6b30662)
parent 2af189a0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4604,6 +4604,8 @@ package android.app {
    method public abstract android.app.FragmentTransaction attach(android.app.Fragment);
    method public abstract int commit();
    method public abstract int commitAllowingStateLoss();
    method public abstract void commitNow();
    method public abstract void commitNowAllowingStateLoss();
    method public abstract android.app.FragmentTransaction detach(android.app.Fragment);
    method public abstract android.app.FragmentTransaction disallowAddToBackStack();
    method public abstract android.app.FragmentTransaction hide(android.app.Fragment);
+2 −0
Original line number Diff line number Diff line
@@ -4737,6 +4737,8 @@ package android.app {
    method public abstract android.app.FragmentTransaction attach(android.app.Fragment);
    method public abstract int commit();
    method public abstract int commitAllowingStateLoss();
    method public abstract void commitNow();
    method public abstract void commitNowAllowingStateLoss();
    method public abstract android.app.FragmentTransaction detach(android.app.Fragment);
    method public abstract android.app.FragmentTransaction disallowAddToBackStack();
    method public abstract android.app.FragmentTransaction hide(android.app.Fragment);
+2 −0
Original line number Diff line number Diff line
@@ -4604,6 +4604,8 @@ package android.app {
    method public abstract android.app.FragmentTransaction attach(android.app.Fragment);
    method public abstract int commit();
    method public abstract int commitAllowingStateLoss();
    method public abstract void commitNow();
    method public abstract void commitNowAllowingStateLoss();
    method public abstract android.app.FragmentTransaction detach(android.app.Fragment);
    method public abstract android.app.FragmentTransaction disallowAddToBackStack();
    method public abstract android.app.FragmentTransaction hide(android.app.Fragment);
+12 −0
Original line number Diff line number Diff line
@@ -667,6 +667,18 @@ final class BackStackRecord extends FragmentTransaction implements
        return commitInternal(true);
    }

    @Override
    public void commitNow() {
        disallowAddToBackStack();
        mManager.execSingleAction(this, false);
    }

    @Override
    public void commitNowAllowingStateLoss() {
        disallowAddToBackStack();
        mManager.execSingleAction(this, true);
    }

    int commitInternal(boolean allowStateLoss) {
        if (mCommitted) {
            throw new IllegalStateException("commit already called");
+26 −1
Original line number Diff line number Diff line
@@ -1503,6 +1503,26 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        }
    }

    public void execSingleAction(Runnable action, boolean allowStateLoss) {
        if (mExecutingActions) {
            throw new IllegalStateException("FragmentManager is already executing transactions");
        }

        if (Looper.myLooper() != mHost.getHandler().getLooper()) {
            throw new IllegalStateException("Must be called from main thread of fragment host");
        }

        if (allowStateLoss) {
            checkStateLoss();
        }

        mExecutingActions = true;
        action.run();
        mExecutingActions = false;

        doPendingDeferredStart();
    }

    /**
     * Only call from main thread!
     */
@@ -1543,6 +1563,12 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
            didSomething = true;
        }

        doPendingDeferredStart();

        return didSomething;
    }

    void doPendingDeferredStart() {
        if (mHavePendingDeferredStart) {
            boolean loadersRunning = false;
            for (int i=0; i<mActive.size(); i++) {
@@ -1556,7 +1582,6 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                startPendingDeferredFragments();
            }
        }
        return didSomething;
    }

    void reportBackStackChanged() {
Loading