Merge "Nested fragments." into jb-mr1-dev

This commit is contained in:
Dianne Hackborn
2012-09-06 11:41:47 -07:00
committed by Android (Google) Code Review
5 changed files with 425 additions and 118 deletions

View File

@@ -3348,6 +3348,7 @@ package android.app {
method public final boolean equals(java.lang.Object);
method public final android.app.Activity getActivity();
method public final android.os.Bundle getArguments();
method public final android.app.FragmentManager getChildFragmentManager();
method public final android.app.FragmentManager getFragmentManager();
method public final int getId();
method public android.app.LoaderManager getLoaderManager();
@@ -3399,6 +3400,7 @@ package android.app {
method public void onStop();
method public void onTrimMemory(int);
method public void onViewCreated(android.view.View, android.os.Bundle);
method public void onViewStateRestored(android.os.Bundle);
method public void registerForContextMenu(android.view.View);
method public void setArguments(android.os.Bundle);
method public void setHasOptionsMenu(boolean);

View File

@@ -653,8 +653,9 @@ public class Activity extends ContextThemeWrapper
/** Start of user-defined activity results. */
public static final int RESULT_FIRST_USER = 1;
static final String FRAGMENTS_TAG = "android:fragments";
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_";
@@ -697,7 +698,7 @@ public class Activity extends ContextThemeWrapper
Object activity;
HashMap<String, Object> children;
ArrayList<Fragment> fragments;
SparseArray<LoaderManagerImpl> loaders;
HashMap<String, LoaderManagerImpl> loaders;
}
/* package */ NonConfigurationInstances mLastNonConfigurationInstances;
@@ -715,8 +716,14 @@ public class Activity extends ContextThemeWrapper
private int mTitleColor = 0;
final FragmentManagerImpl mFragments = new FragmentManagerImpl();
final FragmentContainer mContainer = new FragmentContainer() {
@Override
public View findViewById(int id) {
return Activity.this.findViewById(id);
}
};
SparseArray<LoaderManagerImpl> mAllLoaderManagers;
HashMap<String, LoaderManagerImpl> mAllLoaderManagers;
LoaderManagerImpl mLoaderManager;
private static final class ManagedCursor {
@@ -744,6 +751,7 @@ public class Activity extends ContextThemeWrapper
protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused};
@SuppressWarnings("unused")
private final Object mInstanceTracker = StrictMode.trackActivity(this);
private Thread mUiThread;
@@ -808,19 +816,19 @@ public class Activity extends ContextThemeWrapper
return mLoaderManager;
}
mCheckedForLoaderManager = true;
mLoaderManager = getLoaderManager(-1, mLoadersStarted, true);
mLoaderManager = getLoaderManager(null, mLoadersStarted, true);
return mLoaderManager;
}
LoaderManagerImpl getLoaderManager(int index, boolean started, boolean create) {
LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) {
if (mAllLoaderManagers == null) {
mAllLoaderManagers = new SparseArray<LoaderManagerImpl>();
mAllLoaderManagers = new HashMap<String, LoaderManagerImpl>();
}
LoaderManagerImpl lm = mAllLoaderManagers.get(index);
LoaderManagerImpl lm = mAllLoaderManagers.get(who);
if (lm == null) {
if (create) {
lm = new LoaderManagerImpl(this, started);
mAllLoaderManagers.put(index, lm);
lm = new LoaderManagerImpl(who, this, started);
mAllLoaderManagers.put(who, lm);
}
} else {
lm.updateActivity(this);
@@ -1025,7 +1033,7 @@ public class Activity extends ContextThemeWrapper
if (mLoaderManager != null) {
mLoaderManager.doStart();
} else if (!mCheckedForLoaderManager) {
mLoaderManager = getLoaderManager(-1, mLoadersStarted, false);
mLoaderManager = getLoaderManager(null, mLoadersStarted, false);
}
mCheckedForLoaderManager = true;
}
@@ -1601,13 +1609,17 @@ public class Activity extends ContextThemeWrapper
if (mAllLoaderManagers != null) {
// prune out any loader managers that were already stopped and so
// have nothing useful to retain.
for (int i=mAllLoaderManagers.size()-1; i>=0; i--) {
LoaderManagerImpl lm = mAllLoaderManagers.valueAt(i);
if (lm.mRetaining) {
retainLoaders = true;
} else {
lm.doDestroy();
mAllLoaderManagers.removeAt(i);
LoaderManagerImpl loaders[] = new LoaderManagerImpl[mAllLoaderManagers.size()];
mAllLoaderManagers.values().toArray(loaders);
if (loaders != null) {
for (int i=0; i<loaders.length; i++) {
LoaderManagerImpl lm = loaders[i];
if (lm.mRetaining) {
retainLoaders = true;
} else {
lm.doDestroy();
mAllLoaderManagers.remove(lm.mWho);
}
}
}
}
@@ -1643,13 +1655,13 @@ public class Activity extends ContextThemeWrapper
return mFragments;
}
void invalidateFragmentIndex(int index) {
void invalidateFragment(String who) {
//Log.v(TAG, "invalidateFragmentIndex: index=" + index);
if (mAllLoaderManagers != null) {
LoaderManagerImpl lm = mAllLoaderManagers.get(index);
LoaderManagerImpl lm = mAllLoaderManagers.get(who);
if (lm != null && !lm.mRetaining) {
lm.doDestroy();
mAllLoaderManagers.remove(index);
mAllLoaderManagers.remove(who);
}
}
}
@@ -4739,6 +4751,10 @@ public class Activity extends ContextThemeWrapper
* @param args additional arguments to the dump request.
*/
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
dumpInner(prefix, fd, writer, args);
}
void dumpInner(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
writer.print(prefix); writer.print("Local Activity ");
writer.print(Integer.toHexString(System.identityHashCode(this)));
writer.println(" State:");
@@ -5019,7 +5035,7 @@ public class Activity extends ContextThemeWrapper
Configuration config) {
attachBaseContext(context);
mFragments.attachActivity(this);
mFragments.attachActivity(this, mContainer, null);
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
@@ -5080,10 +5096,14 @@ public class Activity extends ContextThemeWrapper
}
mFragments.dispatchStart();
if (mAllLoaderManagers != null) {
for (int i=mAllLoaderManagers.size()-1; i>=0; i--) {
LoaderManagerImpl lm = mAllLoaderManagers.valueAt(i);
lm.finishRetain();
lm.doReportStart();
LoaderManagerImpl loaders[] = new LoaderManagerImpl[mAllLoaderManagers.size()];
mAllLoaderManagers.values().toArray(loaders);
if (loaders != null) {
for (int i=0; i<loaders.length; i++) {
LoaderManagerImpl lm = loaders[i];
lm.finishRetain();
lm.doReportStart();
}
}
}
}

View File

@@ -85,7 +85,7 @@ final class FragmentState implements Parcelable {
mSavedFragmentState = in.readBundle();
}
public Fragment instantiate(Activity activity) {
public Fragment instantiate(Activity activity, Fragment parent) {
if (mInstance != null) {
return mInstance;
}
@@ -100,7 +100,7 @@ final class FragmentState implements Parcelable {
mSavedFragmentState.setClassLoader(activity.getClassLoader());
mInstance.mSavedFragmentState = mSavedFragmentState;
}
mInstance.setIndex(mIndex);
mInstance.setIndex(mIndex, parent);
mInstance.mFromLayout = mFromLayout;
mInstance.mRestored = true;
mInstance.mFragmentId = mFragmentId;
@@ -207,6 +207,8 @@ final class FragmentState implements Parcelable {
* with the fragment.
* <li> {@link #onActivityCreated} tells the fragment that its activity has
* completed its own {@link Activity#onCreate Activity.onCreate()}.
* <li> {@link #onViewStateRestored} tells the fragment that all of the saved
* state of its view hierarchy has been restored.
* <li> {@link #onStart} makes the fragment visible to the user (based on its
* containing activity being started).
* <li> {@link #onResume} makes the fragment interacting with the user (based on its
@@ -412,7 +414,13 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
// Activity this fragment is attached to.
Activity mActivity;
// Private fragment manager for child fragments inside of this one.
FragmentManagerImpl mChildFragmentManager;
// If this Fragment is contained in another Fragment, this is that container.
Fragment mParentFragment;
// The optional identifier for this fragment -- either the container ID if it
// was dynamically added to the view hierarchy, or the ID supplied in
// layout.
@@ -595,16 +603,26 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
}
}
final void restoreViewState() {
final void restoreViewState(Bundle savedInstanceState) {
if (mSavedViewState != null) {
mView.restoreHierarchyState(mSavedViewState);
mSavedViewState = null;
}
mCalled = false;
onViewStateRestored(savedInstanceState);
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onViewStateRestored()");
}
}
final void setIndex(int index) {
final void setIndex(int index, Fragment parent) {
mIndex = index;
mWho = "android:fragment:" + mIndex;
if (parent != null) {
mWho = parent.mWho + ":" + mIndex;
} else {
mWho = "android:fragment:" + mIndex;
}
}
final boolean isInBackStack() {
@@ -785,11 +803,34 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
* before {@link #getActivity()}, during the time from when the fragment is
* placed in a {@link FragmentTransaction} until it is committed and
* attached to its activity.
*
* <p>If this Fragment is a child of another Fragment, the FragmentManager
* returned here will be the parent's {@link #getChildFragmentManager()}.
*/
final public FragmentManager getFragmentManager() {
return mFragmentManager;
}
/**
* Return a private FragmentManager for placing and managing Fragments
* inside of this Fragment.
*/
final public FragmentManager getChildFragmentManager() {
if (mChildFragmentManager == null) {
instantiateChildFragmentManager();
if (mState >= RESUMED) {
mChildFragmentManager.dispatchResume();
} else if (mState >= STARTED) {
mChildFragmentManager.dispatchStart();
} else if (mState >= ACTIVITY_CREATED) {
mChildFragmentManager.dispatchActivityCreated();
} else if (mState >= CREATED) {
mChildFragmentManager.dispatchCreate();
}
}
return mChildFragmentManager;
}
/**
* Return true if the fragment is currently added to its activity.
*/
@@ -880,6 +921,10 @@ 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;
}
@@ -961,7 +1006,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
mCheckedForLoaderManager = true;
mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true);
mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, true);
return mLoaderManager;
}
@@ -1191,7 +1236,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
* {@link #setRetainInstance(boolean)} to retain their instance,
* as this callback tells the fragment when it is fully associated with
* the new activity instance. This is called after {@link #onCreateView}
* and before {@link #onStart()}.
* and before {@link #onViewStateRestored(Bundle)}.
*
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
@@ -1199,7 +1244,22 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
public void onActivityCreated(Bundle savedInstanceState) {
mCalled = true;
}
/**
* Called when all saved state has been restored into the view hierarchy
* of the fragment. This can be used to do initialization based on saved
* state that you are letting the view hierarchy track itself, such as
* whether check box widgets are currently checked. This is called
* after {@link #onActivityCreated(Bundle)} and before
* {@link #onStart()}.
*
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
*/
public void onViewStateRestored(Bundle savedInstanceState) {
mCalled = true;
}
/**
* Called when the Fragment is visible to the user. This is generally
* tied to {@link Activity#onStart() Activity.onStart} of the containing
@@ -1212,7 +1272,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
mLoadersStarted = true;
if (!mCheckedForLoaderManager) {
mCheckedForLoaderManager = true;
mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false);
mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
mLoaderManager.doStart();
@@ -1305,7 +1365,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
// + " mLoaderManager=" + mLoaderManager);
if (!mCheckedForLoaderManager) {
mCheckedForLoaderManager = true;
mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false);
mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
mLoaderManager.doDestroy();
@@ -1530,6 +1590,14 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
writer.print(prefix); writer.print("mActivity=");
writer.println(mActivity);
}
if (mChildFragmentManager != null) {
writer.print(prefix); writer.print("mChildFragmentManager=");
writer.println(mChildFragmentManager);
}
if (mParentFragment != null) {
writer.print(prefix); writer.print("mParentFragment=");
writer.println(mParentFragment);
}
if (mArguments != null) {
writer.print(prefix); writer.print("mArguments="); writer.println(mArguments);
}
@@ -1564,23 +1632,229 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
writer.print(prefix); writer.println("Loader Manager:");
mLoaderManager.dump(prefix + " ", fd, writer, args);
}
if (mChildFragmentManager != null) {
writer.print(prefix); writer.println("Child Fragment Manager:");
mChildFragmentManager.dump(prefix + " ", fd, writer, args);
}
}
Fragment findFragmentByWho(String who) {
if (who.equals(mWho)) {
return this;
}
if (mChildFragmentManager != null) {
return mChildFragmentManager.findFragmentByWho(who);
}
return null;
}
void instantiateChildFragmentManager() {
mChildFragmentManager = new FragmentManagerImpl();
mChildFragmentManager.attachActivity(mActivity, new FragmentContainer() {
@Override
public View findViewById(int id) {
if (mView == null) {
throw new IllegalStateException("Fragment does not have a view");
}
return mView.findViewById(id);
}
}, this);
}
void performCreate(Bundle savedInstanceState) {
mCalled = false;
onCreate(savedInstanceState);
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onCreate()");
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
if (p != null) {
if (mChildFragmentManager == null) {
instantiateChildFragmentManager();
}
mChildFragmentManager.restoreAllState(p, null);
mChildFragmentManager.dispatchCreate();
}
}
}
void performActivityCreated(Bundle savedInstanceState) {
mCalled = false;
onActivityCreated(savedInstanceState);
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onActivityCreated()");
}
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchActivityCreated();
}
}
void performStart() {
if (mChildFragmentManager != null) {
mChildFragmentManager.noteStateNotSaved();
mChildFragmentManager.execPendingActions();
}
mCalled = false;
onStart();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onStart()");
}
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchStart();
}
if (mLoaderManager != null) {
mLoaderManager.doReportStart();
}
}
void performResume() {
if (mChildFragmentManager != null) {
mChildFragmentManager.execPendingActions();
}
mCalled = false;
onResume();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onResume()");
}
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchResume();
mChildFragmentManager.execPendingActions();
}
}
void performConfigurationChanged(Configuration newConfig) {
onConfigurationChanged(newConfig);
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchConfigurationChanged(newConfig);
}
}
void performLowMemory() {
onLowMemory();
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchLowMemory();
}
}
void performTrimMemory(int level) {
onTrimMemory(level);
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchTrimMemory(level);
}
}
boolean performCreateOptionsMenu(Menu menu, MenuInflater inflater) {
boolean show = false;
if (!mHidden) {
if (mHasMenu && mMenuVisible) {
show = true;
onCreateOptionsMenu(menu, inflater);
}
if (mChildFragmentManager != null) {
show |= mChildFragmentManager.dispatchCreateOptionsMenu(menu, inflater);
}
}
return show;
}
boolean performPrepareOptionsMenu(Menu menu) {
boolean show = false;
if (!mHidden) {
if (mHasMenu && mMenuVisible) {
show = true;
onPrepareOptionsMenu(menu);
}
if (mChildFragmentManager != null) {
show |= mChildFragmentManager.dispatchPrepareOptionsMenu(menu);
}
}
return show;
}
boolean performOptionsItemSelected(MenuItem item) {
if (!mHidden) {
if (mHasMenu && mMenuVisible) {
if (onOptionsItemSelected(item)) {
return true;
}
}
if (mChildFragmentManager != null) {
if (mChildFragmentManager.dispatchOptionsItemSelected(item)) {
return true;
}
}
}
return false;
}
boolean performContextItemSelected(MenuItem item) {
if (!mHidden) {
if (onContextItemSelected(item)) {
return true;
}
if (mChildFragmentManager != null) {
if (mChildFragmentManager.dispatchContextItemSelected(item)) {
return true;
}
}
}
return false;
}
void performOptionsMenuClosed(Menu menu) {
if (!mHidden) {
if (mHasMenu && mMenuVisible) {
onOptionsMenuClosed(menu);
}
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchOptionsMenuClosed(menu);
}
}
}
void performSaveInstanceState(Bundle outState) {
onSaveInstanceState(outState);
if (mChildFragmentManager != null) {
Parcelable p = mChildFragmentManager.saveAllState();
if (p != null) {
outState.putParcelable(Activity.FRAGMENTS_TAG, p);
}
}
}
void performPause() {
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchPause();
}
mCalled = false;
onPause();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onPause()");
}
}
void performStop() {
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchStop();
}
mCalled = false;
onStop();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onStop()");
}
if (mLoadersStarted) {
mLoadersStarted = false;
if (!mCheckedForLoaderManager) {
mCheckedForLoaderManager = true;
mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false);
mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
if (mActivity == null || !mActivity.mChangingConfigurations) {
@@ -1593,9 +1867,29 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
}
void performDestroyView() {
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchDestroyView();
}
mCalled = false;
onDestroyView();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDestroyView()");
}
if (mLoaderManager != null) {
mLoaderManager.doReportNextStart();
}
}
void performDestroy() {
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchDestroy();
}
mCalled = false;
onDestroy();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDestroy()");
}
}
}

View File

@@ -20,7 +20,6 @@ import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
@@ -30,7 +29,6 @@ import android.os.Parcelable;
import android.util.DebugUtils;
import android.util.Log;
import android.util.LogWriter;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuInflater;
@@ -380,6 +378,13 @@ final class FragmentManagerState implements Parcelable {
};
}
/**
* Callbacks from FragmentManagerImpl to its container.
*/
interface FragmentContainer {
public View findViewById(int id);
}
/**
* Container for fragments associated with an activity.
*/
@@ -410,6 +415,8 @@ final class FragmentManagerImpl extends FragmentManager {
int mCurState = Fragment.INITIALIZING;
Activity mActivity;
FragmentContainer mContainer;
Fragment mParent;
boolean mNeedMenuInvalidate;
boolean mStateSaved;
@@ -585,7 +592,11 @@ final class FragmentManagerImpl extends FragmentManager {
sb.append("FragmentManager{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(" in ");
DebugUtils.buildShortClassTag(mActivity, sb);
if (mParent != null) {
DebugUtils.buildShortClassTag(mParent, sb);
} else {
DebugUtils.buildShortClassTag(mActivity, sb);
}
sb.append("}}");
return sb.toString();
}
@@ -681,6 +692,11 @@ final class FragmentManagerImpl extends FragmentManager {
}
writer.print(prefix); writer.println("FragmentManager misc state:");
writer.print(prefix); writer.print(" mActivity="); writer.println(mActivity);
writer.print(prefix); writer.print(" mContainer="); writer.println(mContainer);
if (mParent != null) {
writer.print(prefix); writer.print(" mParent="); writer.println(mParent);
}
writer.print(prefix); writer.print(" mCurState="); writer.print(mCurState);
writer.print(" mStateSaved="); writer.print(mStateSaved);
writer.print(" mDestroyed="); writer.println(mDestroyed);
@@ -809,7 +825,9 @@ final class FragmentManagerImpl extends FragmentManager {
}
}
f.mActivity = mActivity;
f.mFragmentManager = mActivity.mFragments;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mActivity.mFragments;
f.mCalled = false;
f.onAttach(mActivity);
if (!f.mCalled) {
@@ -817,14 +835,9 @@ final class FragmentManagerImpl extends FragmentManager {
+ " did not call through to super.onAttach()");
}
mActivity.onAttachFragment(f);
if (!f.mRetaining) {
f.mCalled = false;
f.onCreate(f.mSavedFragmentState);
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onCreate()");
}
f.performCreate(f.mSavedFragmentState);
}
f.mRetaining = false;
if (f.mFromLayout) {
@@ -845,7 +858,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
container = (ViewGroup)mActivity.findViewById(f.mContainerId);
container = (ViewGroup)mContainer.findViewById(f.mContainerId);
if (container == null && !f.mRestored) {
throwException(new IllegalArgumentException(
"No view found for id 0x"
@@ -873,14 +886,9 @@ final class FragmentManagerImpl extends FragmentManager {
}
}
f.mCalled = false;
f.onActivityCreated(f.mSavedFragmentState);
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onActivityCreated()");
}
f.performActivityCreated(f.mSavedFragmentState);
if (f.mView != null) {
f.restoreViewState();
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
@@ -888,23 +896,13 @@ final class FragmentManagerImpl extends FragmentManager {
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.mCalled = false;
f.performStart();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onStart()");
}
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.mCalled = false;
f.mResumed = true;
f.onResume();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onResume()");
}
f.performResume();
// Get rid of this in case we saved it and never needed it.
f.mSavedFragmentState = null;
f.mSavedViewState = null;
@@ -915,23 +913,13 @@ final class FragmentManagerImpl extends FragmentManager {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
f.mCalled = false;
f.onPause();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onPause()");
}
f.performPause();
f.mResumed = false;
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.mCalled = false;
f.performStop();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onStop()");
}
}
case Fragment.STOPPED:
case Fragment.ACTIVITY_CREATED:
@@ -944,12 +932,7 @@ final class FragmentManagerImpl extends FragmentManager {
saveFragmentViewState(f);
}
}
f.mCalled = false;
f.performDestroyView();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onDestroyView()");
}
if (f.mView != null && f.mContainer != null) {
Animator anim = null;
if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
@@ -1008,12 +991,7 @@ final class FragmentManagerImpl extends FragmentManager {
} else {
if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
if (!f.mRetaining) {
f.mCalled = false;
f.onDestroy();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onDestroy()");
}
f.performDestroy();
}
f.mCalled = false;
@@ -1027,6 +1005,7 @@ final class FragmentManagerImpl extends FragmentManager {
makeInactive(f);
} else {
f.mActivity = null;
f.mParentFragment = null;
f.mFragmentManager = null;
}
}
@@ -1050,11 +1029,11 @@ final class FragmentManagerImpl extends FragmentManager {
if (mActivity == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
if (!always && mCurState == newState) {
return;
}
mCurState = newState;
if (mActive != null) {
boolean loadersRunning = false;
@@ -1099,11 +1078,11 @@ final class FragmentManagerImpl extends FragmentManager {
if (mActive == null) {
mActive = new ArrayList<Fragment>();
}
f.setIndex(mActive.size());
f.setIndex(mActive.size(), mParent);
mActive.add(f);
} else {
f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1));
f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
mActive.set(f.mIndex, f);
}
if (DEBUG) Log.v(TAG, "Allocated fragment index " + f);
@@ -1120,7 +1099,7 @@ final class FragmentManagerImpl extends FragmentManager {
mAvailIndices = new ArrayList<Integer>();
}
mAvailIndices.add(f.mIndex);
mActivity.invalidateFragmentIndex(f.mIndex);
mActivity.invalidateFragment(f.mWho);
f.initState();
}
@@ -1296,7 +1275,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (mActive != null && who != null) {
for (int i=mActive.size()-1; i>=0; i--) {
Fragment f = mActive.get(i);
if (f != null && who.equals(f.mWho)) {
if (f != null && (f=f.findFragmentByWho(who)) != null) {
return f;
}
}
@@ -1566,7 +1545,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (mStateBundle == null) {
mStateBundle = new Bundle();
}
f.onSaveInstanceState(mStateBundle);
f.performSaveInstanceState(mStateBundle);
if (!mStateBundle.isEmpty()) {
result = mStateBundle;
mStateBundle = null;
@@ -1735,7 +1714,7 @@ final class FragmentManagerImpl extends FragmentManager {
for (int i=0; i<fms.mActive.length; i++) {
FragmentState fs = fms.mActive[i];
if (fs != null) {
Fragment f = fs.instantiate(mActivity);
Fragment f = fs.instantiate(mActivity, mParent);
if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": " + f);
mActive.add(f);
// Now that the fragment is instantiated (or came from being
@@ -1803,9 +1782,11 @@ final class FragmentManagerImpl extends FragmentManager {
}
}
public void attachActivity(Activity activity) {
public void attachActivity(Activity activity, FragmentContainer container, Fragment parent) {
if (mActivity != null) throw new IllegalStateException("Already attached");
mActivity = activity;
mContainer = container;
mParent = parent;
}
public void noteStateNotSaved() {
@@ -1840,11 +1821,17 @@ final class FragmentManagerImpl extends FragmentManager {
moveToState(Fragment.STOPPED, false);
}
public void dispatchDestroyView() {
moveToState(Fragment.CREATED, false);
}
public void dispatchDestroy() {
mDestroyed = true;
execPendingActions();
moveToState(Fragment.INITIALIZING, false);
mActivity = null;
mContainer = null;
mParent = null;
}
public void dispatchConfigurationChanged(Configuration newConfig) {
@@ -1852,7 +1839,7 @@ final class FragmentManagerImpl extends FragmentManager {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null) {
f.onConfigurationChanged(newConfig);
f.performConfigurationChanged(newConfig);
}
}
}
@@ -1863,7 +1850,7 @@ final class FragmentManagerImpl extends FragmentManager {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null) {
f.onLowMemory();
f.performLowMemory();
}
}
}
@@ -1874,7 +1861,7 @@ final class FragmentManagerImpl extends FragmentManager {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null) {
f.onTrimMemory(level);
f.performTrimMemory(level);
}
}
}
@@ -1886,13 +1873,14 @@ final class FragmentManagerImpl extends FragmentManager {
if (mAdded != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
show = true;
f.onCreateOptionsMenu(menu, inflater);
if (newMenus == null) {
newMenus = new ArrayList<Fragment>();
if (f != null) {
if (f.performCreateOptionsMenu(menu, inflater)) {
show = true;
if (newMenus == null) {
newMenus = new ArrayList<Fragment>();
}
newMenus.add(f);
}
newMenus.add(f);
}
}
}
@@ -1916,9 +1904,10 @@ final class FragmentManagerImpl extends FragmentManager {
if (mAdded != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
show = true;
f.onPrepareOptionsMenu(menu);
if (f != null) {
if (f.performPrepareOptionsMenu(menu)) {
show = true;
}
}
}
}
@@ -1929,8 +1918,8 @@ final class FragmentManagerImpl extends FragmentManager {
if (mAdded != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
if (f.onOptionsItemSelected(item)) {
if (f != null) {
if (f.performOptionsItemSelected(item)) {
return true;
}
}
@@ -1943,8 +1932,8 @@ final class FragmentManagerImpl extends FragmentManager {
if (mAdded != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null && !f.mHidden) {
if (f.onContextItemSelected(item)) {
if (f != null) {
if (f.performContextItemSelected(item)) {
return true;
}
}
@@ -1957,8 +1946,8 @@ final class FragmentManagerImpl extends FragmentManager {
if (mAdded != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
f.onOptionsMenuClosed(menu);
if (f != null) {
f.performOptionsMenuClosed(menu);
}
}
}

View File

@@ -17,7 +17,6 @@
package android.app;
import android.content.Loader;
import android.content.Loader.OnLoadCanceledListener;
import android.os.Bundle;
import android.util.DebugUtils;
import android.util.Log;
@@ -213,6 +212,8 @@ class LoaderManagerImpl extends LoaderManager {
// previously run loader until the new loader's data is available.
final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>();
final String mWho;
Activity mActivity;
boolean mStarted;
boolean mRetaining;
@@ -529,7 +530,8 @@ class LoaderManagerImpl extends LoaderManager {
}
}
LoaderManagerImpl(Activity activity, boolean started) {
LoaderManagerImpl(String who, Activity activity, boolean started) {
mWho = who;
mActivity = activity;
mStarted = started;
}