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

Commit 3d44416d authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Further work on fragments:"

parents 8d64c9bb b4bc78b1
Loading
Loading
Loading
Loading
+119 −8
Original line number Diff line number Diff line
@@ -19904,6 +19904,19 @@
<parameter name="id" type="int">
</parameter>
</method>
<method name="findFragmentByTag"
 return="android.app.Fragment"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="tag" type="java.lang.String">
</parameter>
</method>
<method name="findViewById"
 return="android.view.View"
 abstract="false"
@@ -25414,6 +25427,19 @@
 visibility="public"
>
</constructor>
<method name="equals"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="o" type="java.lang.Object">
</parameter>
</method>
<method name="getActivity"
 return="android.app.Activity"
 abstract="false"
@@ -25425,6 +25451,61 @@
 visibility="public"
>
</method>
<method name="getId"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getRetainInstance"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getTag"
 return="java.lang.String"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getView"
 return="android.view.View"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="hashCode"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="onAttach"
 return="void"
 abstract="false"
@@ -25493,6 +25574,8 @@
</parameter>
<parameter name="container" type="android.view.ViewGroup">
</parameter>
<parameter name="savedInstanceState" type="android.os.Bundle">
</parameter>
</method>
<method name="onDestroy"
 return="void"
@@ -25553,7 +25636,7 @@
 visibility="public"
>
</method>
<method name="onRestoreInstanceState"
<method name="onReady"
 return="void"
 abstract="false"
 native="false"
@@ -25577,8 +25660,8 @@
 visibility="public"
>
</method>
<method name="onRetainNonConfigurationInstance"
 return="java.lang.Object"
<method name="onSaveInstanceState"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
@@ -25587,8 +25670,10 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="outState" type="android.os.Bundle">
</parameter>
</method>
<method name="onSaveInstanceState"
<method name="onStart"
 return="void"
 abstract="false"
 native="false"
@@ -25598,10 +25683,8 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="outState" type="android.os.Bundle">
</parameter>
</method>
<method name="onStart"
<method name="onStop"
 return="void"
 abstract="false"
 native="false"
@@ -25612,7 +25695,7 @@
 visibility="public"
>
</method>
<method name="onStop"
<method name="setRetainInstance"
 return="void"
 abstract="false"
 native="false"
@@ -25622,6 +25705,8 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="retain" type="boolean">
</parameter>
</method>
</class>
<interface name="FragmentTransaction"
@@ -25643,6 +25728,8 @@
>
<parameter name="fragment" type="android.app.Fragment">
</parameter>
<parameter name="tag" type="java.lang.String">
</parameter>
</method>
<method name="add"
 return="android.app.FragmentTransaction"
@@ -181501,6 +181588,17 @@
 visibility="public"
>
</method>
<method name="isSaveFromParentEnabled"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="isScrollbarFadingEnabled"
 return="boolean"
 abstract="false"
@@ -182979,6 +183077,19 @@
<parameter name="enabled" type="boolean">
</parameter>
</method>
<method name="setSaveFromParentEnabled"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="enabled" type="boolean">
</parameter>
</method>
<method name="setScrollBarStyle"
 return="void"
 abstract="false"
+97 −192
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteException;
import android.text.Selection;
import android.text.SpannableStringBuilder;
@@ -77,6 +78,9 @@ import android.widget.LinearLayout;
import com.android.internal.app.SplitActionBar;
import com.android.internal.policy.PolicyManager;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * An activity is a single, focused thing that the user can do.  Almost all
 * activities interact with the user, so the Activity class takes care of
@@ -611,6 +615,7 @@ public class Activity extends ContextThemeWrapper
    private static long sInstanceCount = 0;

    private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState";
    private static final String FRAGMENTS_TAG = "android:fragments";
    private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds";
    private static final String SAVED_DIALOGS_TAG = "android:savedDialogs";
    private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_";
@@ -632,8 +637,6 @@ public class Activity extends ContextThemeWrapper
    private ComponentName mComponent;
    /*package*/ ActivityInfo mActivityInfo;
    /*package*/ ActivityThread mMainThread;
    /*package*/ Object mLastNonConfigurationInstance;
    /*package*/ HashMap<String,Object> mLastNonConfigurationChildInstances;
    Activity mParent;
    boolean mCalled;
    private boolean mResumed;
@@ -646,6 +649,13 @@ public class Activity extends ContextThemeWrapper
    /*package*/ Configuration mCurrentConfig;
    private SearchManager mSearchManager;

    static final class NonConfigurationInstances {
        Object activity;
        HashMap<String, Object> children;
        ArrayList<Fragment> fragments;
    }
    /* package */ NonConfigurationInstances mLastNonConfigurationInstances;
    
    private Window mWindow;

    private WindowManager mWindowManager;
@@ -660,148 +670,6 @@ public class Activity extends ContextThemeWrapper

    final FragmentManager mFragments = new FragmentManager();
    
    private final Object[] sConstructorArgs = new Object[0];

    private static final Class[] sConstructorSignature = new Class[] { };

    private static final HashMap<String, Constructor> sConstructorMap =
            new HashMap<String, Constructor>();
    
    private final class FragmentTransactionImpl implements FragmentTransaction,
            Runnable, BackStackState {
        ArrayList<Fragment> mAdded;
        ArrayList<Fragment> mRemoved;
        int mTransition;
        int mTransitionStyle;
        boolean mAddToBackStack;
        String mName;
        boolean mCommitted;
        
        public FragmentTransaction add(Fragment fragment) {
            return add(fragment, 0);
        }

        public FragmentTransaction add(Fragment fragment, int containerViewId) {
            if (fragment.mActivity != null) {
                throw new IllegalStateException("Fragment already added: " + fragment);
            }
            if (mRemoved != null) {
                mRemoved.remove(fragment);
            }
            if (mAdded == null) {
                mAdded = new ArrayList<Fragment>();
            }
            fragment.mContainerId = containerViewId;
            mAdded.add(fragment);
            return this;
        }

        public FragmentTransaction replace(Fragment fragment, int containerViewId) {
            if (containerViewId == 0) {
                throw new IllegalArgumentException("Must use non-zero containerViewId");
            }
            if (mFragments.mFragments != null) {
                for (int i=0; i<mFragments.mFragments.size(); i++) {
                    Fragment old = mFragments.mFragments.get(i);
                    if (old.mContainerId == containerViewId) {
                        remove(old);
                    }
                }
            }
            return add(fragment, containerViewId);
        }
        
        public FragmentTransaction remove(Fragment fragment) {
            if (fragment.mActivity == null) {
                throw new IllegalStateException("Fragment not added: " + fragment);
            }
            if (mAdded != null) {
                mAdded.remove(fragment);
            }
            if (mRemoved == null) {
                mRemoved = new ArrayList<Fragment>();
            }
            mRemoved.add(fragment);
            return this;
        }

        public FragmentTransaction setTransition(int transition) {
            mTransition = transition;
            return this;
        }
        
        public FragmentTransaction setTransitionStyle(int styleRes) {
            mTransitionStyle = styleRes;
            return this;
        }
        
        public FragmentTransaction addToBackStack(String name) {
            mAddToBackStack = true;
            mName = name;
            return this;
        }

        public void commit() {
            if (mCommitted) throw new IllegalStateException("commit already called");
            mCommitted = true;
            mHandler.post(this);
        }
        
        public void run() {
            if (mRemoved != null) {
                for (int i=mRemoved.size()-1; i>=0; i--) {
                    mFragments.removeFragment(mRemoved.get(i), mTransition,
                            mTransitionStyle);
                }
            }
            if (mAdded != null) {
                for (int i=mAdded.size()-1; i>=0; i--) {
                    Fragment f = mAdded.get(i);
                    mFragments.addFragment(f, false);
                    if (mAddToBackStack) {
                        f.mBackStackNesting++;
                    }
                }
            }
            mFragments.moveToState(mFragments.mCurState, mTransition,
                    mTransitionStyle, true);
            if (mAddToBackStack) {
                mFragments.addBackStackState(this);
            }
        }
        
        public void popFromBackStack() {
            if (mAdded != null) {
                for (int i=mAdded.size()-1; i>=0; i--) {
                    Fragment f = mAdded.get(i);
                    if (mAddToBackStack) {
                        f.mBackStackNesting--;
                    }
                    mFragments.removeFragment(f,
                            FragmentManager.reverseTransit(mTransition),
                            mTransitionStyle);
                }
            }
            if (mRemoved != null) {
                for (int i=mRemoved.size()-1; i>=0; i--) {
                    mFragments.addFragment(mRemoved.get(i), false);
                }
            }
        }
        
        public String getName() {
            return mName;
        }
        
        public int getTransition() {
            return mTransition;
        }
        
        public int getTransitionStyle() {
            return mTransitionStyle;
        }
    }
    
    private static final class ManagedCursor {
        ManagedCursor(Cursor cursor) {
            mCursor = cursor;
@@ -828,7 +696,7 @@ public class Activity extends ContextThemeWrapper
    protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused};

    private Thread mUiThread;
    private final Handler mHandler = new Handler();
    final Handler mHandler = new Handler();

    // Used for debug only
    /*
@@ -952,7 +820,12 @@ public class Activity extends ContextThemeWrapper
    protected void onCreate(Bundle savedInstanceState) {
        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchCreate(savedInstanceState);
        if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                    ? mLastNonConfigurationInstances.fragments : null);
        }
        mFragments.dispatchCreate();
        mCalled = true;
    }

@@ -1237,6 +1110,10 @@ public class Activity extends ContextThemeWrapper
     */
    protected void onSaveInstanceState(Bundle outState) {
        outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
        Parcelable p = mFragments.saveAllState();
        if (p != null) {
            outState.putParcelable(FRAGMENTS_TAG, p);
        }
    }

    /**
@@ -1541,7 +1418,8 @@ public class Activity extends ContextThemeWrapper
     * {@link #onRetainNonConfigurationInstance()}.
     */
    public Object getLastNonConfigurationInstance() {
        return mLastNonConfigurationInstance;
        return mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.activity : null;
    }
    
    /**
@@ -1598,7 +1476,8 @@ public class Activity extends ContextThemeWrapper
     * {@link #onRetainNonConfigurationChildInstances()}
     */
    HashMap<String, Object> getLastNonConfigurationChildInstances() {
        return mLastNonConfigurationChildInstances;
        return mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.children : null;
    }
    
    /**
@@ -1612,6 +1491,21 @@ public class Activity extends ContextThemeWrapper
        return null;
    }
    
    NonConfigurationInstances retainNonConfigurationInstances() {
        Object activity = onRetainNonConfigurationInstance();
        HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
        ArrayList<Fragment> fragments = mFragments.retainNonConfig();
        if (activity == null && children == null && fragments == null) {
            return null;
        }
        
        NonConfigurationInstances nci = new NonConfigurationInstances();
        nci.activity = activity;
        nci.children = children;
        nci.fragments = fragments;
        return nci;
    }
    
    public void onLowMemory() {
        mCalled = true;
    }
@@ -1621,7 +1515,7 @@ public class Activity extends ContextThemeWrapper
     * this activity.
     */
    public FragmentTransaction openFragmentTransaction() {
        return new FragmentTransactionImpl();
        return new BackStackEntry(mFragments);
    }
    
    /**
@@ -1810,16 +1704,6 @@ public class Activity extends ContextThemeWrapper
        return mActionBar;
    }
    
    /**
     * Finds a fragment that was identified by the given id either when inflated
     * from XML or as the container ID when added in a transaction.  This only
     * returns fragments that are currently added to the activity's content.
     * @return The fragment if found or null otherwise.
     */
    public Fragment findFragmentById(int id) {
        return mFragments.findFragmentById(id);
    }
    
    /**
     * Creates a new ActionBar, locates the inflated ActionBarView,
     * initializes the ActionBar with the view, and sets mActionBar.
@@ -1841,6 +1725,26 @@ public class Activity extends ContextThemeWrapper
        }
    }
    
    /**
     * Finds a fragment that was identified by the given id either when inflated
     * from XML or as the container ID when added in a transaction.  This only
     * returns fragments that are currently added to the activity's content.
     * @return The fragment if found or null otherwise.
     */
    public Fragment findFragmentById(int id) {
        return mFragments.findFragmentById(id);
    }
    
    /**
     * Finds a fragment that was identified by the given tag either when inflated
     * from XML or as supplied when added in a transaction.  This only
     * returns fragments that are currently added to the activity's content.
     * @return The fragment if found or null otherwise.
     */
    public Fragment findFragmentByTag(String tag) {
        return mFragments.findFragmentByTag(tag);
    }
    
    /**
     * Set the activity content from a layout resource.  The resource will be
     * inflated, adding all top-level views to the activity.
@@ -2198,6 +2102,11 @@ public class Activity extends ContextThemeWrapper
    }

    public void onContentChanged() {
        // First time content is available, let the fragment manager
        // attach all of the fragments to it.
        if (mFragments.mCurState < Fragment.CONTENT) {
            mFragments.moveToState(Fragment.CONTENT, false);
        }
    }

    /**
@@ -3960,44 +3869,42 @@ public class Activity extends ContextThemeWrapper
        TypedArray a = 
            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Fragment);
        String fname = a.getString(com.android.internal.R.styleable.Fragment_name);
        int id = a.getInt(com.android.internal.R.styleable.Fragment_id, 0);
        int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, 0);
        String tag = a.getString(com.android.internal.R.styleable.Fragment_tag);
        a.recycle();
        
        Constructor constructor = sConstructorMap.get(fname);
        Class clazz = null;
        if (id == 0) {
            throw new IllegalArgumentException(attrs.getPositionDescription()
                    + ": Must specify unique android:id for " + fname);
        }
        
        try {
            if (constructor == null) {
                // Class not found in the cache, see if it's real, and try to add it
                clazz = getClassLoader().loadClass(fname);
                constructor = clazz.getConstructor(sConstructorSignature);
                sConstructorMap.put(fname, constructor);
            }
            Fragment fragment = (Fragment)constructor.newInstance(sConstructorArgs);
            // If we restored from a previous state, we may already have
            // instantiated this fragment from the state and should use
            // that instance instead of making a new one.
            Fragment fragment = mFragments.findFragmentById(id);
            if (fragment == null) {
                fragment = Fragment.instantiate(this, fname);
                fragment.mFromLayout = true;
                fragment.mFragmentId = id;
                fragment.mTag = tag;
                fragment.onInflate(this, attrs);
                mFragments.addFragment(fragment, true);
            }
            if (fragment.mView == null) {
                throw new IllegalStateException("Fragment " + fname
                        + " did not create a view.");
            }
            fragment.mView.setId(id);
            if (fragment.mView.getTag() == null) {
                fragment.mView.setTag(tag);
            }
            return fragment.mView;

        } catch (NoSuchMethodException e) {
            InflateException ie = new InflateException(attrs.getPositionDescription()
                    + ": Error inflating class " + fname);
            ie.initCause(e);
            throw ie;

        } catch (ClassNotFoundException e) {
            // If loadClass fails, we should propagate the exception.
            throw new RuntimeException(e);
        } catch (Exception e) {
            InflateException ie = new InflateException(attrs.getPositionDescription()
                    + ": Error inflating class "
                    + (clazz == null ? "<unknown>" : clazz.getName()));
                    + ": Error inflating fragment " + fname);
            ie.initCause(e);
            throw new RuntimeException(ie);
            throw ie;
        }
    }

@@ -4009,18 +3916,17 @@ public class Activity extends ContextThemeWrapper

    final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,
            Application application, Intent intent, ActivityInfo info, CharSequence title, 
            Activity parent, String id, Object lastNonConfigurationInstance,
            Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config) {
        attach(context, aThread, instr, token, 0, application, intent, info, title, parent, id,
            lastNonConfigurationInstance, null, config);
            lastNonConfigurationInstances, config);
    }
    
    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            Object lastNonConfigurationInstance,
            HashMap<String,Object> lastNonConfigurationChildInstances,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config) {
        attachBaseContext(context);

@@ -4045,8 +3951,7 @@ public class Activity extends ContextThemeWrapper
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstance = lastNonConfigurationInstance;
        mLastNonConfigurationChildInstances = lastNonConfigurationChildInstances;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;

        mWindow.setWindowManager(null, mToken, mComponent.flattenToString());
        if (mParent != null) {
@@ -4104,7 +4009,7 @@ public class Activity extends ContextThemeWrapper
    final void performResume() {
        performRestart();
        
        mLastNonConfigurationInstance = null;
        mLastNonConfigurationInstances = null;
        
        // First call onResume() -before- setting mResumed, so we don't
        // send out any status bar / menu notifications the client makes.
+7 −22
Original line number Diff line number Diff line
@@ -1300,8 +1300,7 @@ public final class ActivityThread {
        Window window;
        Activity parent;
        String embeddedID;
        Object lastNonConfigurationInstance;
        HashMap<String,Object> lastNonConfigurationChildInstances;
        Activity.NonConfigurationInstances lastNonConfigurationInstances;
        boolean paused;
        boolean stopped;
        boolean hideForNow;
@@ -2479,7 +2478,7 @@ public final class ActivityThread {

    public final Activity startActivityNow(Activity parent, String id,
        Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
        Object lastNonConfigurationInstance) {
        Activity.NonConfigurationInstances lastNonConfigurationInstances) {
        ActivityRecord r = new ActivityRecord();
            r.token = token;
            r.ident = 0;
@@ -2488,7 +2487,7 @@ public final class ActivityThread {
            r.parent = parent;
            r.embeddedID = id;
            r.activityInfo = activityInfo;
            r.lastNonConfigurationInstance = lastNonConfigurationInstance;
            r.lastNonConfigurationInstances = lastNonConfigurationInstances;
        if (localLOGV) {
            ComponentName compname = intent.getComponent();
            String name;
@@ -2610,14 +2609,12 @@ public final class ActivityThread {
                        + r.activityInfo.name + " with config " + config);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstance,
                        r.lastNonConfigurationChildInstances, config);
                        r.embeddedID, r.lastNonConfigurationInstances, config);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstance = null;
                r.lastNonConfigurationChildInstances = null;
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
@@ -3618,8 +3615,8 @@ public final class ActivityThread {
            }
            if (getNonConfigInstance) {
                try {
                    r.lastNonConfigurationInstance
                            = r.activity.onRetainNonConfigurationInstance();
                    r.lastNonConfigurationInstances
                            = r.activity.retainNonConfigurationInstances();
                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
@@ -3628,18 +3625,6 @@ public final class ActivityThread {
                                + ": " + e.toString(), e);
                    }
                }
                try {
                    r.lastNonConfigurationChildInstances
                            = r.activity.onRetainNonConfigurationChildInstances();
                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
                                "Unable to retain child activities "
                                + safeToComponentShortString(r.intent)
                                + ": " + e.toString(), e);
                    }
                }

            }
            try {
                r.activity.mCalled = false;
+308 −10

File changed.

Preview size limit exceeded, changes collapsed.

+541 −47

File changed.

Preview size limit exceeded, changes collapsed.

Loading