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

Commit 3e449ce0 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Some fragment stuff:

Fix issue #2975886: Make getTargetFragment() survive rotation events with
retained fragments.  We now fix up the fragment pointer when restoring state.

Fix issue #2919928: In PreferenceFragment, addPreferencesFromResources() is
not effective when called after onActivityCreated().  Note to self: do not use
a what code of 0.  Maybe that should be documented (I'll do it in gingerbread).

Hopefully implement #2992753: DialogFragment.dismiss will NPE if called too soon
(before attached to activity).  We now keep track of the FragmentManager
separately from the activity, and set that as soon as the fragment is part of a
transaction.

Investigate issue #2988876: NPE when device orientation is changed.  The NPE is
because of the app trying to do a fragment transaction in onPause().  This is
fundamentally not viable, since (a) the activity will be gone before we ever
have a chance to process the message to commit the transaction, and (b) even if
we did try to commit the transaction earlier, this would be done after
onSaveInstanceState() and thus not work in cases where the activity gets killed
in the background.  So instead, we'll just throw an immediate exception if you
try to do this.

Change-Id: Iea62b50eb79f066af2471fce86836d073398f4f7
parent 2f761760
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4058,6 +4058,7 @@ public class Activity extends ContextThemeWrapper
            fragment.mFragmentId = id;
            fragment.mTag = tag;
            fragment.mImmediateActivity = this;
            fragment.mFragmentManager = mFragments;
            // If this fragment is newly instantiated (either right now, or
            // from last saved state), then give it the attributes to
            // initialize itself.
+1 −0
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ final class BackStackEntry implements FragmentTransaction, Runnable {
            throw new IllegalStateException("Fragment already added: " + fragment);
        }
        fragment.mImmediateActivity = mManager.mActivity;
        fragment.mFragmentManager = mManager;
        
        if (tag != null) {
            if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
+11 −2
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ final class FragmentState implements Parcelable {
        mInstance.mContainerId = mContainerId;
        mInstance.mTag = mTag;
        mInstance.mRetainInstance = mRetainInstance;
        mInstance.mFragmentManager = activity.mFragments;
        
        return mInstance;
    }
@@ -318,6 +319,11 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
    // Number of active back stack entries this fragment is in.
    int mBackStackNesting;
    
    // 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;

    // Set as soon as a fragment is added to a transaction (or removed),
    // to be able to do validation.
    Activity mImmediateActivity;
@@ -578,10 +584,13 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
    
    /**
     * Return the FragmentManager for interacting with fragments associated
     * with this fragment's activity.
     * with this fragment's activity.  Note that this will be non-null slightly
     * before {@link #getActivity()}, in the time from when the fragment is
     * placed in a {@link FragmentTransaction} until it is committed and
     * attached to its activity.
     */
    final public FragmentManager getFragmentManager() {
        return mActivity.mFragments;
        return mFragmentManager;
    }

    /**
+28 −0
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ final class FragmentManagerImpl implements FragmentManager {
    Activity mActivity;
    
    boolean mNeedMenuInvalidate;
    boolean mStateSaved;
    
    // Temporary vars for state save and restore.
    Bundle mStateBundle = null;
@@ -484,6 +485,7 @@ final class FragmentManagerImpl implements FragmentManager {
                            throw new SuperNotCalledException("Fragment " + f
                                    + " did not call through to super.onDetach()");
                        }
                        f.mImmediateActivity = null;
                        f.mActivity = null;
                    }
            }
@@ -678,6 +680,10 @@ final class FragmentManagerImpl implements FragmentManager {
    }
    
    public void enqueueAction(Runnable action) {
        if (mStateSaved) {
            throw new IllegalStateException(
                    "Can not perform this action after onSaveInstanceState");
        }
        synchronized (this) {
            if (mPendingActions == null) {
                mPendingActions = new ArrayList<Runnable>();
@@ -888,6 +894,8 @@ final class FragmentManagerImpl implements FragmentManager {
    }
    
    Parcelable saveAllState() {
        mStateSaved = true;

        if (mActive == null || mActive.size() <= 0) {
            return null;
        }
@@ -1029,6 +1037,22 @@ final class FragmentManagerImpl implements FragmentManager {
            }
        }
        
        // Update the target of all retained fragments.
        if (nonConfig != null) {
            for (int i=0; i<nonConfig.size(); i++) {
                Fragment f = nonConfig.get(i);
                if (f.mTarget != null) {
                    if (f.mTarget.mIndex < mActive.size()) {
                        f.mTarget = mActive.get(f.mTarget.mIndex);
                    } else {
                        Log.w(TAG, "Re-attaching retained fragment " + f
                                + " target no longer exists: " + f.mTarget);
                        f.mTarget = null;
                    }
                }
            }
        }

        // Build the list of currently added fragments.
        if (fms.mAdded != null) {
            mAdded = new ArrayList<Fragment>(fms.mAdded.length);
@@ -1070,18 +1094,22 @@ final class FragmentManagerImpl implements FragmentManager {
    }
    
    public void dispatchCreate() {
        mStateSaved = false;
        moveToState(Fragment.CREATED, false);
    }
    
    public void dispatchActivityCreated() {
        mStateSaved = false;
        moveToState(Fragment.ACTIVITY_CREATED, false);
    }
    
    public void dispatchStart() {
        mStateSaved = false;
        moveToState(Fragment.STARTED, false);
    }
    
    public void dispatchResume() {
        mStateSaved = false;
        moveToState(Fragment.RESUMED, false);
    }
    
+2 −2
Original line number Diff line number Diff line
@@ -180,8 +180,8 @@ public abstract class PreferenceActivity extends ListActivity implements
     */
    private static final int FIRST_REQUEST_CODE = 100;

    private static final int MSG_BIND_PREFERENCES = 0;
    private static final int MSG_BUILD_HEADERS = 1;
    private static final int MSG_BIND_PREFERENCES = 1;
    private static final int MSG_BUILD_HEADERS = 2;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
Loading