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

Commit 6e8304e5 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

More fragment stuff:

- New startActivityForResult() API.
- Fragments now should have the correct lifecycle while hanging around
  in the back stack (not being destroyed and re-created).
- Rework of state save/restore to make it simpler and better.  In theory
  now any fragment (including layout and others in the hierarchy) can
  now be retained across config changes, though this hasn't been tested.

Change-Id: I2a7fe560e14e567f5675a2f172a23fca67b3e97f
parent 41b5fc5c
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
@@ -21504,6 +21504,23 @@
<parameter name="requestCode" type="int">
</parameter>
</method>
<method name="startActivityFromFragment"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="fragment" type="android.app.Fragment">
</parameter>
<parameter name="intent" type="android.content.Intent">
</parameter>
<parameter name="requestCode" type="int">
</parameter>
</method>
<method name="startActivityIfNeeded"
 return="boolean"
 abstract="false"
@@ -25506,6 +25523,23 @@
 visibility="public"
>
</method>
<method name="onActivityResult"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="requestCode" type="int">
</parameter>
<parameter name="resultCode" type="int">
</parameter>
<parameter name="data" type="android.content.Intent">
</parameter>
</method>
<method name="onAttach"
 return="void"
 abstract="false"
@@ -25613,6 +25647,8 @@
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
<parameter name="savedInstanceState" type="android.os.Bundle">
</parameter>
</method>
<method name="onLowMemory"
 return="void"
@@ -25708,6 +25744,34 @@
<parameter name="retain" type="boolean">
</parameter>
</method>
<method name="startActivity"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="intent" type="android.content.Intent">
</parameter>
</method>
<method name="startActivityForResult"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="intent" type="android.content.Intent">
</parameter>
<parameter name="requestCode" type="int">
</parameter>
</method>
</class>
<interface name="FragmentTransaction"
 abstract="true"
+42 −4
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.app;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;

@@ -3161,6 +3160,36 @@ public class Activity extends ContextThemeWrapper
        }
    }

    /**
     * This is called when a Fragment in this activity calls its 
     * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult}
     * method.
     * 
     * <p>This method throws {@link android.content.ActivityNotFoundException}
     * if there was no Activity found to run the given Intent.
     * 
     * @param fragment The fragment making the call.
     * @param intent The intent to start.
     * @param requestCode Reply request code.  < 0 if reply is not requested. 
     * 
     * @throws android.content.ActivityNotFoundException
     * 
     * @see Fragment#startActivity 
     * @see Fragment#startActivityForResult 
     */
    public void startActivityFromFragment(Fragment fragment, Intent intent, 
            int requestCode) {
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, fragment,
                intent, requestCode);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, fragment.mWho, requestCode,
                ar.getResultCode(), ar.getResultData());
        }
    }

    /**
     * Like {@link #startActivityFromChild(Activity, Intent, int)}, but
     * taking a IntentSender; see
@@ -3433,8 +3462,7 @@ public class Activity extends ContextThemeWrapper
     * @see #createPendingResult
     * @see #setResult(int)
     */
    protected void onActivityResult(int requestCode, int resultCode,
            Intent data) {
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    }

    /**
@@ -3854,9 +3882,14 @@ public class Activity extends ContextThemeWrapper
                fragment.mFromLayout = true;
                fragment.mFragmentId = id;
                fragment.mTag = tag;
                fragment.onInflate(this, attrs);
                mFragments.addFragment(fragment, true);
            }
            // If this fragment is newly instantiated (either right now, or
            // from last saved state), then give it the attributes to
            // initialize itself.
            if (!fragment.mRetaining) {
                fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
            }
            if (fragment.mView == null) {
                throw new IllegalStateException("Fragment " + fname
                        + " did not create a view.");
@@ -4059,6 +4092,11 @@ public class Activity extends ContextThemeWrapper
            + ", resCode=" + resultCode + ", data=" + data);
        if (who == null) {
            onActivityResult(requestCode, resultCode, data);
        } else {
            Fragment frag = mFragments.findFragmentByWho(who);
            if (frag != null) {
                frag.onActivityResult(requestCode, resultCode, data);
            }
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -620,7 +620,8 @@ class ContextImpl extends Context {
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity)null, intent, -1);
    }

    @Override
+70 −15
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app;

import android.content.ComponentCallbacks;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Parcel;
@@ -36,8 +37,8 @@ final class FragmentState implements Parcelable {
    static final String VIEW_STATE_TAG = "android:view_state";
    
    final String mClassName;
    final int mIndex;
    final boolean mFromLayout;
    final int mSavedStateId;
    final int mFragmentId;
    final int mContainerId;
    final String mTag;
@@ -49,8 +50,8 @@ final class FragmentState implements Parcelable {
    
    public FragmentState(Fragment frag) {
        mClassName = frag.getClass().getName();
        mIndex = frag.mIndex;
        mFromLayout = frag.mFromLayout;
        mSavedStateId = frag.mSavedStateId;
        mFragmentId = frag.mFragmentId;
        mContainerId = frag.mContainerId;
        mTag = frag.mTag;
@@ -59,8 +60,8 @@ final class FragmentState implements Parcelable {
    
    public FragmentState(Parcel in) {
        mClassName = in.readString();
        mIndex = in.readInt();
        mFromLayout = in.readInt() != 0;
        mSavedStateId = in.readInt();
        mFragmentId = in.readInt();
        mContainerId = in.readInt();
        mTag = in.readString();
@@ -69,10 +70,6 @@ final class FragmentState implements Parcelable {
    }
    
    public Fragment instantiate(Activity activity) {
        if (mFromLayout) {
            return null;
        }
        
        if (mInstance != null) {
            return mInstance;
        }
@@ -89,7 +86,8 @@ final class FragmentState implements Parcelable {
            mInstance.mSavedViewState
                    = mSavedFragmentState.getSparseParcelableArray(VIEW_STATE_TAG);
        }
        mInstance.mSavedStateId = mSavedStateId;
        mInstance.setIndex(mIndex);
        mInstance.mFromLayout = mFromLayout;
        mInstance.mFragmentId = mFragmentId;
        mInstance.mContainerId = mContainerId;
        mInstance.mTag = mTag;
@@ -104,8 +102,8 @@ final class FragmentState implements Parcelable {

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mClassName);
        dest.writeInt(mIndex);
        dest.writeInt(mFromLayout ? 1 : 0);
        dest.writeInt(mSavedStateId);
        dest.writeInt(mFragmentId);
        dest.writeInt(mContainerId);
        dest.writeString(mTag);
@@ -149,6 +147,15 @@ public class Fragment implements ComponentCallbacks {
    Bundle mSavedFragmentState;
    SparseArray<Parcelable> mSavedViewState;
    
    // Index into active fragment array.
    int mIndex = -1;
    
    // Internal unique name for this fragment;
    String mWho;
    
    // True if the fragment is in the list of added fragments.
    boolean mAdded;
    
    // Set to true if this fragment was instantiated from a layout file.
    boolean mFromLayout;
    
@@ -187,10 +194,6 @@ public class Fragment implements ComponentCallbacks {
    // The View generated for this fragment.
    View mView;
    
    // Used for performing save state of fragments.
    int mSavedStateSeq = 0;
    int mSavedStateId;
    
    public Fragment() {
    }

@@ -217,6 +220,16 @@ public class Fragment implements ComponentCallbacks {
        }
    }
    
    void setIndex(int index) {
        mIndex = index;
        mWho = "android:fragment:" + mIndex;
   }
    
    void clearIndex() {
        mIndex = -1;
        mWho = null;
    }
    
    /**
     * Subclasses can not override equals().
     */
@@ -276,15 +289,57 @@ public class Fragment implements ComponentCallbacks {
        return mRetainInstance;
    }
    
    /**
     * Call {@link Activity#startActivity(Intent)} on the fragment's
     * containing Activity.
     */
    public void startActivity(Intent intent) {
        mActivity.startActivityFromFragment(this, intent, -1);
    }
    
    /**
     * Call {@link Activity#startActivityForResult(Intent, int)} on the fragment's
     * containing Activity.
     */
    public void startActivityForResult(Intent intent, int requestCode) {
        mActivity.startActivityFromFragment(this, intent, requestCode);
    }
    
    /**
     * Receive the result from a previous call to
     * {@link #startActivityForResult(Intent, int)}.  This follows the
     * related Activity API as described there in
     * {@link Activity#onActivityResult(int, int, Intent)}.
     * 
     * @param requestCode The integer request code originally supplied to
     *                    startActivityForResult(), allowing you to identify who this
     *                    result came from.
     * @param resultCode The integer result code returned by the child activity
     *                   through its setResult().
     * @param data An Intent, which can return result data to the caller
     *               (various data can be attached to Intent "extras").
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    }
    
    /**
     * Called when a fragment is being created as part of a view layout
     * inflation, typically from setting the content view of an activity.
     * inflation, typically from setting the content view of an activity.  This
     * will be called both the first time the fragment is created, as well
     * later when it is being re-created from its saved state (which is also
     * given here).
     * 
     * XXX This is kind-of yucky...  maybe we could just supply the
     * AttributeSet to onCreate()?
     * 
     * @param activity The Activity that is inflating the fragment.
     * @param attrs The attributes at the tag where the fragment is
     * being created.
     * @param savedInstanceState If the fragment is being re-created from
     * a previous saved state, this is the state.
     */
    public void onInflate(Activity activity, AttributeSet attrs) {
    public void onInflate(Activity activity, AttributeSet attrs,
            Bundle savedInstanceState) {
        mCalled = true;
    }
    
+192 −127

File changed.

Preview size limit exceeded, changes collapsed.

Loading