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

Commit 592df7d8 authored by Adam Powell's avatar Adam Powell
Browse files

Init child fragments consistently with activity fragments

Fragments contained within an activity are restored from instance
state in FragmentActivity.onCreate, but fragments contained within
another fragment were previously restored from instance state in
performCreate after onCreate returned. This meant that developers
couldn't consistently rely on being able to control when this happens
with a call to super.onCreate, and calls to findFragmentByTag to
reconnect with a restored child fragment would fail in ways that
succeed when the fragment is directly added to an activity.

Change child fragment instance state restore to happen during
Fragment.onCreate instead of in performCreate to be consistent with
activity behavior. Preserve the old behavior for apps targeting
an SDK version < N.

Change-Id: I9c88d5554da9a32219d64c70ca638f75ecb233ed
parent 395371c1
Loading
Loading
Loading
Loading
+31 −7
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -1416,11 +1417,30 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * at this point.  If you want to do work once the activity itself is
     * created, see {@link #onActivityCreated(Bundle)}.
     *
     * <p>If your app's <code>targetSdkVersion</code> is 23 or lower, child fragments
     * being restored from the savedInstanceState are restored after <code>onCreate</code>
     * returns. When targeting N or above and running on an N or newer platform version
     * they are restored by <code>Fragment.onCreate</code>.</p>
     *
     * @param savedInstanceState If the fragment is being re-created from
     * a previous saved state, this is the state.
     */
    public void onCreate(@Nullable Bundle savedInstanceState) {
        mCalled = true;
        final Context context = getContext();
        final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
        if (version >= Build.VERSION_CODES.N) {
            if (savedInstanceState != null) {
                Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
                if (p != null) {
                    if (mChildFragmentManager == null) {
                        instantiateChildFragmentManager();
                    }
                    mChildFragmentManager.restoreAllState(p, null);
                    mChildFragmentManager.dispatchCreate();
                }
            }
        }
    }

    /**
@@ -2210,6 +2230,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
            throw new SuperNotCalledException("Fragment " + this
                    + " did not call through to super.onCreate()");
        }
        final Context context = getContext();
        final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
        if (version < Build.VERSION_CODES.N) {
            if (savedInstanceState != null) {
                Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
                if (p != null) {
@@ -2221,6 +2244,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
                }
            }
        }
    }

    View performCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {