summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-06-10 18:39:48 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2011-06-10 18:39:48 -0700
commitfc441bfff9eb68be08eb922ea05c78c5d6fba27a (patch)
tree2c9d44d02f940bc4221769157fd83fe84c8f3b58 /core
parent5fe24ec77d183774dfb06262b80b32be608480c7 (diff)
parentfd63814abe8e81d5e1e0eb75b5a5a18034e9b4c6 (diff)
downloadframeworks_base-fc441bfff9eb68be08eb922ea05c78c5d6fba27a.zip
frameworks_base-fc441bfff9eb68be08eb922ea05c78c5d6fba27a.tar.gz
frameworks_base-fc441bfff9eb68be08eb922ea05c78c5d6fba27a.tar.bz2
am fd63814a: Merge "Fix some problems with moving in and out of detached state." into honeycomb-mr2
* commit 'fd63814abe8e81d5e1e0eb75b5a5a18034e9b4c6': Fix some problems with moving in and out of detached state.
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/app/Fragment.java57
-rw-r--r--core/java/android/app/FragmentManager.java6
-rw-r--r--core/java/android/app/ListFragment.java24
-rw-r--r--core/java/android/app/LoaderManager.java33
5 files changed, 107 insertions, 17 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b739e10..e0a2ce8 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4413,7 +4413,9 @@ public class Activity extends ContextThemeWrapper
mFragments.dispatchStart();
if (mAllLoaderManagers != null) {
for (int i=mAllLoaderManagers.size()-1; i>=0; i--) {
- mAllLoaderManagers.valueAt(i).finishRetain();
+ LoaderManagerImpl lm = mAllLoaderManagers.valueAt(i);
+ lm.finishRetain();
+ lm.doReportStart();
}
}
}
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 14ffd3b..f2be9ad 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -587,11 +587,6 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
mWho = "android:fragment:" + mIndex;
}
- final void clearIndex() {
- mIndex = -1;
- mWho = null;
- }
-
final boolean isInBackStack() {
return mBackStackNesting > 0;
}
@@ -783,6 +778,15 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
}
/**
+ * Return true if the fragment has been explicitly detached from the UI.
+ * That is, {@link FragmentTransaction#detach(Fragment)
+ * FragmentTransaction.detach(Fragment)} has been used on it.
+ */
+ final public boolean isDetached() {
+ return mDetached;
+ }
+
+ /**
* Return true if this fragment is currently being removed from its
* activity. This is <em>not</em> whether its activity is finishing, but
* rather whether it is in the process of being removed from its activity.
@@ -1203,6 +1207,35 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
}
/**
+ * Called by the fragment manager once this fragment has been removed,
+ * so that we don't have any left-over state if the application decides
+ * to re-use the instance. This only clears state that the framework
+ * internally manages, not things the application sets.
+ */
+ void initState() {
+ mIndex = -1;
+ mWho = null;
+ mAdded = false;
+ mRemoving = false;
+ mResumed = false;
+ mFromLayout = false;
+ mInLayout = false;
+ mRestored = false;
+ mBackStackNesting = 0;
+ mFragmentManager = null;
+ mActivity = mImmediateActivity = null;
+ mFragmentId = 0;
+ mContainerId = 0;
+ mTag = null;
+ mHidden = false;
+ mDetached = false;
+ mRetaining = false;
+ mLoaderManager = null;
+ mLoadersStarted = false;
+ mCheckedForLoaderManager = false;
+ }
+
+ /**
* Called when the fragment is no longer attached to its activity. This
* is called after {@link #onDestroy()}.
*/
@@ -1429,6 +1462,13 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
}
}
+ void performStart() {
+ onStart();
+ if (mLoaderManager != null) {
+ mLoaderManager.doReportStart();
+ }
+ }
+
void performStop() {
onStop();
@@ -1447,4 +1487,11 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
}
}
}
+
+ void performDestroyView() {
+ onDestroyView();
+ if (mLoaderManager != null) {
+ mLoaderManager.doReportNextStart();
+ }
+ }
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 3b2e108..f05e2b3 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -803,7 +803,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.mCalled = false;
- f.onStart();
+ f.performStart();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onStart()");
@@ -856,7 +856,7 @@ final class FragmentManagerImpl extends FragmentManager {
}
}
f.mCalled = false;
- f.onDestroyView();
+ f.performDestroyView();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onDestroyView()");
@@ -1006,7 +1006,7 @@ final class FragmentManagerImpl extends FragmentManager {
}
mAvailIndices.add(f.mIndex);
mActivity.invalidateFragmentIndex(f.mIndex);
- f.clearIndex();
+ f.initState();
}
public void addFragment(Fragment fragment, boolean moveToStateNow) {
diff --git a/core/java/android/app/ListFragment.java b/core/java/android/app/ListFragment.java
index a5ee26c..dc8420e 100644
--- a/core/java/android/app/ListFragment.java
+++ b/core/java/android/app/ListFragment.java
@@ -167,7 +167,7 @@ public class ListFragment extends Fragment {
TextView mStandardEmptyView;
View mProgressContainer;
View mListContainer;
- boolean mSetEmptyText;
+ CharSequence mEmptyText;
boolean mListShown;
public ListFragment() {
@@ -210,6 +210,9 @@ public class ListFragment extends Fragment {
public void onDestroyView() {
mHandler.removeCallbacks(mRequestFocus);
mList = null;
+ mListShown = false;
+ mEmptyView = mProgressContainer = mListContainer = null;
+ mStandardEmptyView = null;
super.onDestroyView();
}
@@ -289,10 +292,10 @@ public class ListFragment extends Fragment {
throw new IllegalStateException("Can't be used with a custom content view");
}
mStandardEmptyView.setText(text);
- if (!mSetEmptyText) {
+ if (mEmptyText == null) {
mList.setEmptyView(mStandardEmptyView);
- mSetEmptyText = true;
}
+ mEmptyText = text;
}
/**
@@ -346,6 +349,9 @@ public class ListFragment extends Fragment {
getActivity(), android.R.anim.fade_out));
mListContainer.startAnimation(AnimationUtils.loadAnimation(
getActivity(), android.R.anim.fade_in));
+ } else {
+ mProgressContainer.clearAnimation();
+ mListContainer.clearAnimation();
}
mProgressContainer.setVisibility(View.GONE);
mListContainer.setVisibility(View.VISIBLE);
@@ -355,6 +361,9 @@ public class ListFragment extends Fragment {
getActivity(), android.R.anim.fade_in));
mListContainer.startAnimation(AnimationUtils.loadAnimation(
getActivity(), android.R.anim.fade_out));
+ } else {
+ mProgressContainer.clearAnimation();
+ mListContainer.clearAnimation();
}
mProgressContainer.setVisibility(View.VISIBLE);
mListContainer.setVisibility(View.GONE);
@@ -383,6 +392,8 @@ public class ListFragment extends Fragment {
com.android.internal.R.id.internalEmpty);
if (mStandardEmptyView == null) {
mEmptyView = root.findViewById(android.R.id.empty);
+ } else {
+ mStandardEmptyView.setVisibility(View.GONE);
}
mProgressContainer = root.findViewById(com.android.internal.R.id.progressContainer);
mListContainer = root.findViewById(com.android.internal.R.id.listContainer);
@@ -400,12 +411,17 @@ public class ListFragment extends Fragment {
}
if (mEmptyView != null) {
mList.setEmptyView(mEmptyView);
+ } else if (mEmptyText != null) {
+ mStandardEmptyView.setText(mEmptyText);
+ mList.setEmptyView(mStandardEmptyView);
}
}
mListShown = true;
mList.setOnItemClickListener(mOnClickListener);
if (mAdapter != null) {
- setListAdapter(mAdapter);
+ ListAdapter adapter = mAdapter;
+ mAdapter = null;
+ setListAdapter(adapter);
} else {
// We are starting without an adapter, so assume we won't
// have our data right away and start with the progress indicator.
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 164141c..46a008d 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -223,6 +223,7 @@ class LoaderManagerImpl extends LoaderManager {
boolean mStarted;
boolean mRetaining;
boolean mRetainingStarted;
+ boolean mReportNextStart;
boolean mDestroyed;
boolean mListenerRegistered;
@@ -291,7 +292,7 @@ class LoaderManagerImpl extends LoaderManager {
}
}
- if (mStarted && mHaveData) {
+ if (mStarted && mHaveData && !mReportNextStart) {
// This loader has retained its data, either completely across
// a configuration change or just whatever the last data set
// was after being restarted from a stop, and now at the point of
@@ -302,6 +303,17 @@ class LoaderManagerImpl extends LoaderManager {
}
}
+ void reportStart() {
+ if (mStarted) {
+ if (mReportNextStart) {
+ mReportNextStart = false;
+ if (mHaveData) {
+ callOnLoadFinished(mLoader, mData);
+ }
+ }
+ }
+ }
+
void stop() {
if (DEBUG) Log.v(TAG, " Stopping: " + this);
mStarted = false;
@@ -449,10 +461,11 @@ class LoaderManagerImpl extends LoaderManager {
writer.print(prefix); writer.print("mData="); writer.println(mData);
}
writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
- writer.print(" mRetaining="); writer.print(mRetaining);
+ writer.print(" mReportNextStart="); writer.print(mReportNextStart);
writer.print(" mDestroyed="); writer.println(mDestroyed);
- writer.print(prefix); writer.print("mListenerRegistered=");
- writer.println(mListenerRegistered);
+ writer.print(prefix); writer.print("mRetaining="); writer.print(mRetaining);
+ writer.print(" mRetainingStarted="); writer.print(mRetainingStarted);
+ writer.print(" mListenerRegistered="); writer.println(mListenerRegistered);
if (mPendingLoader != null) {
writer.print(prefix); writer.println("Pending Loader ");
writer.print(mPendingLoader); writer.println(":");
@@ -740,6 +753,18 @@ class LoaderManagerImpl extends LoaderManager {
}
}
+ void doReportNextStart() {
+ for (int i = mLoaders.size()-1; i >= 0; i--) {
+ mLoaders.valueAt(i).mReportNextStart = true;
+ }
+ }
+
+ void doReportStart() {
+ for (int i = mLoaders.size()-1; i >= 0; i--) {
+ mLoaders.valueAt(i).reportStart();
+ }
+ }
+
void doDestroy() {
if (!mRetaining) {
if (DEBUG) Log.v(TAG, "Destroying Active in " + this);