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

Commit 65793dc0 authored by Adam Powell's avatar Adam Powell Committed by Android (Google) Code Review
Browse files

Merge "Add API for deferring fragment start." into ics-mr1

parents 43eed003 635c60af
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3245,6 +3245,7 @@ package android.app {
    method public final boolean isInLayout();
    method public final boolean isRemoving();
    method public final boolean isResumed();
    method public boolean isStartDeferred();
    method public final boolean isVisible();
    method public void onActivityCreated(android.os.Bundle);
    method public void onActivityResult(int, int, android.content.Intent);
@@ -3280,6 +3281,7 @@ package android.app {
    method public void setInitialSavedState(android.app.Fragment.SavedState);
    method public void setMenuVisibility(boolean);
    method public void setRetainInstance(boolean);
    method public void setStartDeferred(boolean);
    method public void setTargetFragment(android.app.Fragment, int);
    method public void startActivity(android.content.Intent);
    method public void startActivityForResult(android.content.Intent, int);
+34 −1
Original line number Diff line number Diff line
@@ -339,6 +339,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
    private static final HashMap<String, Class<?>> sClassMap =
            new HashMap<String, Class<?>>();
    
    static final int INVALID_STATE = -1;   // Invalid state used as a null value.
    static final int INITIALIZING = 0;     // Not yet created.
    static final int CREATED = 1;          // Created.
    static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
@@ -403,7 +404,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
    // The fragment manager we are associated with.  Set as soon as the
    // fragment is used in a transaction; cleared after it has been removed
    // from all transactions.
    FragmentManager mFragmentManager;
    FragmentManagerImpl mFragmentManager;

    // Activity this fragment is attached to.
    Activity mActivity;
@@ -453,6 +454,10 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
    // The View generated for this fragment.
    View mView;
    
    // Whether this fragment should defer starting until after other fragments
    // have been started and their loaders are finished.
    boolean mDeferStart;

    LoaderManagerImpl mLoaderManager;
    boolean mLoadersStarted;
    boolean mCheckedForLoaderManager;
@@ -909,6 +914,34 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
        }
    }

    /**
     * Set whether this fragment should enter the started state as normal or if
     * start should be deferred until a system-determined convenient time, such
     * as after any loaders have completed their work.
     *
     * <p>This option is not sticky across fragment starts; after a deferred start
     * completes this option will be set to false.</p>
     *
     * @param deferResume true if this fragment can defer its resume until after others
     */
    public void setStartDeferred(boolean deferResume) {
        if (mDeferStart && !deferResume) {
            mFragmentManager.performPendingDeferredStart(this);
        }
        mDeferStart = deferResume;
    }

    /**
     * Returns true if this fragment's move to the started state has been deferred.
     * If this returns true it will be started once other fragments' loaders
     * have finished running.
     *
     * @return true if this fragment's start has been deferred.
     */
    public boolean isStartDeferred() {
        return mDeferStart;
    }

    /**
     * Return the LoaderManager for this fragment, creating it if needed.
     */
+28 −1
Original line number Diff line number Diff line
@@ -709,6 +709,13 @@ final class FragmentManagerImpl extends FragmentManager {
        return AnimatorInflater.loadAnimator(mActivity, anim);
    }
    
    public void performPendingDeferredStart(Fragment f) {
        if (f.mDeferStart) {
            f.mDeferStart = false;
            moveToState(f, mCurState, 0, 0);
        }
    }

    void moveToState(Fragment f, int newState, int transit, int transitionStyle) {
        // Fragments that are not currently added will sit in the onCreate() state.
        if (!f.mAdded && newState > Fragment.CREATED) {
@@ -718,7 +725,10 @@ final class FragmentManagerImpl extends FragmentManager {
            // While removing a fragment, we can't change it to a higher state.
            newState = f.mState;
        }
        
        // Defer start if requested; don't allow it to move to STARTED or higher.
        if (f.mDeferStart && newState > Fragment.STOPPED) {
            newState = Fragment.STOPPED;
        }
        if (f.mState < newState) {
            // For fragments that are created from a layout, when restoring from
            // state we don't want to allow them to be created until they are
@@ -992,11 +1002,19 @@ final class FragmentManagerImpl extends FragmentManager {
        
        mCurState = newState;
        if (mActive != null) {
            boolean loadersRunning = false;
            for (int i=0; i<mActive.size(); i++) {
                Fragment f = mActive.get(i);
                if (f != null) {
                    moveToState(f, newState, transit, transitStyle);
                    if (f.mLoaderManager != null) {
                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                    }
                }
            }

            if (!loadersRunning) {
                startPendingDeferredFragments();
            }

            if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {
@@ -1006,6 +1024,15 @@ final class FragmentManagerImpl extends FragmentManager {
        }
    }
    
    void startPendingDeferredFragments() {
        for (int i=0; i<mActive.size(); i++) {
            Fragment f = mActive.get(i);
            if (f != null) {
                performPendingDeferredStart(f);
            }
        }
    }

    void makeActive(Fragment f) {
        if (f.mIndex >= 0) {
            return;
+14 −0
Original line number Diff line number Diff line
@@ -418,6 +418,10 @@ class LoaderManagerImpl extends LoaderManager {
                info.destroy();
                mInactiveLoaders.remove(mId);
            }

            if (!hasRunningLoaders() && mActivity != null) {
                mActivity.mFragments.startPendingDeferredFragments();
            }
        }

        void callOnLoadFinished(Loader<Object> loader, Object data) {
@@ -820,4 +824,14 @@ class LoaderManagerImpl extends LoaderManager {
            }
        }
    }

    public boolean hasRunningLoaders() {
        boolean loadersRunning = false;
        final int count = mLoaders.size();
        for (int i = 0; i < count; i++) {
            final LoaderInfo li = mLoaders.valueAt(i);
            loadersRunning |= li.mStarted && !li.mDeliveredData;
        }
        return loadersRunning;
    }
}