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

Commit 44ba79e4 authored by Adam Powell's avatar Adam Powell
Browse files

Permit setRetainInstance(true) on nested fragments, framework edition

Save arbitrarily nested fragments across config changes as
nonconfiguration objects. This permits the use of retain-instance
child fragments as arbitrary opaque dependencies within other
fragments.

Change-Id: Ia6640b76cfcf7ec28ba252628957a0c14863e957
(cherry picked from commit 7466be66)
parent 8585ed66
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -4531,10 +4531,12 @@ package android.app {
    method public void noteStateNotSaved();
    method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
    method public void reportLoaderStart();
    method public void restoreAllState(android.os.Parcelable, java.util.List<android.app.Fragment>);
    method public deprecated void restoreAllState(android.os.Parcelable, java.util.List<android.app.Fragment>);
    method public void restoreAllState(android.os.Parcelable, android.app.FragmentManagerNonConfig);
    method public void restoreLoaderNonConfig(android.util.ArrayMap<java.lang.String, android.app.LoaderManager>);
    method public android.util.ArrayMap<java.lang.String, android.app.LoaderManager> retainLoaderNonConfig();
    method public java.util.List<android.app.Fragment> retainNonConfig();
    method public android.app.FragmentManagerNonConfig retainNestedNonConfig();
    method public deprecated java.util.List<android.app.Fragment> retainNonConfig();
    method public android.os.Parcelable saveAllState();
  }
@@ -4594,6 +4596,9 @@ package android.app {
    method public abstract void onBackStackChanged();
  }
  public class FragmentManagerNonConfig {
  }
  public abstract class FragmentTransaction {
    ctor public FragmentTransaction();
    method public abstract android.app.FragmentTransaction add(android.app.Fragment, java.lang.String);
+7 −2
Original line number Diff line number Diff line
@@ -4664,10 +4664,12 @@ package android.app {
    method public void noteStateNotSaved();
    method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
    method public void reportLoaderStart();
    method public void restoreAllState(android.os.Parcelable, java.util.List<android.app.Fragment>);
    method public deprecated void restoreAllState(android.os.Parcelable, java.util.List<android.app.Fragment>);
    method public void restoreAllState(android.os.Parcelable, android.app.FragmentManagerNonConfig);
    method public void restoreLoaderNonConfig(android.util.ArrayMap<java.lang.String, android.app.LoaderManager>);
    method public android.util.ArrayMap<java.lang.String, android.app.LoaderManager> retainLoaderNonConfig();
    method public java.util.List<android.app.Fragment> retainNonConfig();
    method public android.app.FragmentManagerNonConfig retainNestedNonConfig();
    method public deprecated java.util.List<android.app.Fragment> retainNonConfig();
    method public android.os.Parcelable saveAllState();
  }
@@ -4727,6 +4729,9 @@ package android.app {
    method public abstract void onBackStackChanged();
  }
  public class FragmentManagerNonConfig {
  }
  public abstract class FragmentTransaction {
    ctor public FragmentTransaction();
    method public abstract android.app.FragmentTransaction add(android.app.Fragment, java.lang.String);
+7 −2
Original line number Diff line number Diff line
@@ -4531,10 +4531,12 @@ package android.app {
    method public void noteStateNotSaved();
    method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
    method public void reportLoaderStart();
    method public void restoreAllState(android.os.Parcelable, java.util.List<android.app.Fragment>);
    method public deprecated void restoreAllState(android.os.Parcelable, java.util.List<android.app.Fragment>);
    method public void restoreAllState(android.os.Parcelable, android.app.FragmentManagerNonConfig);
    method public void restoreLoaderNonConfig(android.util.ArrayMap<java.lang.String, android.app.LoaderManager>);
    method public android.util.ArrayMap<java.lang.String, android.app.LoaderManager> retainLoaderNonConfig();
    method public java.util.List<android.app.Fragment> retainNonConfig();
    method public android.app.FragmentManagerNonConfig retainNestedNonConfig();
    method public deprecated java.util.List<android.app.Fragment> retainNonConfig();
    method public android.os.Parcelable saveAllState();
  }
@@ -4594,6 +4596,9 @@ package android.app {
    method public abstract void onBackStackChanged();
  }
  public class FragmentManagerNonConfig {
  }
  public abstract class FragmentTransaction {
    ctor public FragmentTransaction();
    method public abstract android.app.FragmentTransaction add(android.app.Fragment, java.lang.String);
+2 −2
Original line number Diff line number Diff line
@@ -753,7 +753,7 @@ public class Activity extends ContextThemeWrapper
    static final class NonConfigurationInstances {
        Object activity;
        HashMap<String, Object> children;
        List<Fragment> fragments;
        FragmentManagerNonConfig fragments;
        ArrayMap<String, LoaderManager> loaders;
        VoiceInteractor voiceInteractor;
    }
@@ -2070,7 +2070,7 @@ public class Activity extends ContextThemeWrapper
    NonConfigurationInstances retainNonConfigurationInstances() {
        Object activity = onRetainNonConfigurationInstance();
        HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
        List<Fragment> fragments = mFragments.retainNonConfig();
        FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();
        ArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig();
        if (activity == null && children == null && fragments == null && loaders == null
                && mVoiceInteractor == null) {
+32 −32
Original line number Diff line number Diff line
@@ -97,11 +97,9 @@ final class FragmentState implements Parcelable {
        mSavedFragmentState = in.readBundle();
    }

    public Fragment instantiate(FragmentHostCallback host, Fragment parent) {
        if (mInstance != null) {
            return mInstance;
        }

    public Fragment instantiate(FragmentHostCallback host, Fragment parent,
            FragmentManagerNonConfig childNonConfig) {
        if (mInstance == null) {
            final Context context = host.getContext();
            if (mArguments != null) {
                mArguments.setClassLoader(context.getClassLoader());
@@ -125,7 +123,8 @@ final class FragmentState implements Parcelable {
            mInstance.mFragmentManager = host.mFragmentManager;
            if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
                    "Instantiated fragment " + mInstance);

        }
        mInstance.mChildNonConfig = childNonConfig;
        return mInstance;
    }

@@ -433,6 +432,10 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
    // Private fragment manager for child fragments inside of this one.
    FragmentManagerImpl mChildFragmentManager;

    // For use when restoring fragment state and descendant fragments are retained.
    // This state is set by FragmentState.instantiate and cleared in onCreate.
    FragmentManagerNonConfig mChildNonConfig;

    // If this Fragment is contained in another Fragment, this is that container.
    Fragment mParentFragment;

@@ -975,10 +978,6 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * </ul>
     */
    public void setRetainInstance(boolean retain) {
        if (retain && mParentFragment != null) {
            throw new IllegalStateException(
                    "Can't retain fragements that are nested in other fragments");
        }
        mRetainInstance = retain;
    }

@@ -1436,7 +1435,8 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
                    if (mChildFragmentManager == null) {
                        instantiateChildFragmentManager();
                    }
                    mChildFragmentManager.restoreAllState(p, null);
                    mChildFragmentManager.restoreAllState(p, mChildNonConfig);
                    mChildNonConfig = null;
                    mChildFragmentManager.dispatchCreate();
                }
            }
Loading