Move child FragmentManager shutdown for retained fragments
Some apps out there do some creative things in terms of calling their own onDetach methods from elsewhere. Perform the child FragmentManager shutdown for retained fragments in a package-level perform method instead of in onDetach itself. Also mark all existing fragment methods with @CallSuper. Bug 28293847 Change-Id: I343b610f8d427fe5cabd523a78fbf0e6f3b34c57
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package android.app;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.annotation.CallSuper;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringRes;
|
||||
@@ -1335,6 +1336,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@CallSuper
|
||||
public void onInflate(AttributeSet attrs, Bundle savedInstanceState) {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1381,6 +1383,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* @param savedInstanceState If the fragment is being re-created from
|
||||
* a previous saved state, this is the state.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
|
||||
onInflate(attrs, savedInstanceState);
|
||||
mCalled = true;
|
||||
@@ -1421,6 +1424,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@CallSuper
|
||||
public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1429,6 +1433,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* Called when a fragment is first attached to its context.
|
||||
* {@link #onCreate(Bundle)} will be called after this.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onAttach(Context context) {
|
||||
mCalled = true;
|
||||
final Activity hostActivity = mHost == null ? null : mHost.getActivity();
|
||||
@@ -1442,6 +1447,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* @deprecated Use {@link #onAttach(Context)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@CallSuper
|
||||
public void onAttach(Activity activity) {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1473,6 +1479,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* @param savedInstanceState If the fragment is being re-created from
|
||||
* a previous saved state, this is the state.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
mCalled = true;
|
||||
final Context context = getContext();
|
||||
@@ -1558,6 +1565,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* @param savedInstanceState If the fragment is being re-created from
|
||||
* a previous saved state, this is the state.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1573,6 +1581,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* @param savedInstanceState If the fragment is being re-created from
|
||||
* a previous saved state, this is the state.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onViewStateRestored(Bundle savedInstanceState) {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1582,6 +1591,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* tied to {@link Activity#onStart() Activity.onStart} of the containing
|
||||
* Activity's lifecycle.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onStart() {
|
||||
mCalled = true;
|
||||
|
||||
@@ -1603,6 +1613,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* tied to {@link Activity#onResume() Activity.onResume} of the containing
|
||||
* Activity's lifecycle.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onResume() {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1648,6 +1659,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1657,6 +1669,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* tied to {@link Activity#onPause() Activity.onPause} of the containing
|
||||
* Activity's lifecycle.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onPause() {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1666,14 +1679,17 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* tied to {@link Activity#onStop() Activity.onStop} of the containing
|
||||
* Activity's lifecycle.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onStop() {
|
||||
mCalled = true;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onLowMemory() {
|
||||
mCalled = true;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onTrimMemory(int level) {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1687,6 +1703,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* non-null view. Internally it is called after the view's state has
|
||||
* been saved but before it has been removed from its parent.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onDestroyView() {
|
||||
mCalled = true;
|
||||
}
|
||||
@@ -1695,6 +1712,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* Called when the fragment is no longer in use. This is called
|
||||
* after {@link #onStop()} and before {@link #onDetach()}.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onDestroy() {
|
||||
mCalled = true;
|
||||
//Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
|
||||
@@ -1743,20 +1761,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
* Activity re-creation (see {@link #setRetainInstance(boolean)}), in which case it is called
|
||||
* after {@link #onStop()}.
|
||||
*/
|
||||
@CallSuper
|
||||
public void onDetach() {
|
||||
mCalled = true;
|
||||
|
||||
// Destroy the child FragmentManager if we still have it here.
|
||||
// We won't unless we're retaining our instance and if we do,
|
||||
// our child FragmentManager instance state will have already been saved.
|
||||
if (mChildFragmentManager != null) {
|
||||
if (!mRetaining) {
|
||||
throw new IllegalStateException("Child FragmentManager of " + this + " was not "
|
||||
+ " destroyed and this fragment is not retaining instance");
|
||||
}
|
||||
mChildFragmentManager.dispatchDestroy();
|
||||
mChildFragmentManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2568,6 +2575,27 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
|
||||
mChildFragmentManager = null;
|
||||
}
|
||||
|
||||
void performDetach() {
|
||||
mCalled = false;
|
||||
onDetach();
|
||||
if (!mCalled) {
|
||||
throw new SuperNotCalledException("Fragment " + this
|
||||
+ " did not call through to super.onDetach()");
|
||||
}
|
||||
|
||||
// Destroy the child FragmentManager if we still have it here.
|
||||
// We won't unless we're retaining our instance and if we do,
|
||||
// our child FragmentManager instance state will have already been saved.
|
||||
if (mChildFragmentManager != null) {
|
||||
if (!mRetaining) {
|
||||
throw new IllegalStateException("Child FragmentManager of " + this + " was not "
|
||||
+ " destroyed and this fragment is not retaining instance");
|
||||
}
|
||||
mChildFragmentManager.dispatchDestroy();
|
||||
mChildFragmentManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Transition loadTransition(Context context, TypedArray typedArray,
|
||||
Transition currentValue, Transition defaultValue, int id) {
|
||||
if (currentValue != defaultValue) {
|
||||
|
||||
@@ -1117,12 +1117,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
f.mState = Fragment.INITIALIZING;
|
||||
}
|
||||
|
||||
f.mCalled = false;
|
||||
f.onDetach();
|
||||
if (!f.mCalled) {
|
||||
throw new SuperNotCalledException("Fragment " + f
|
||||
+ " did not call through to super.onDetach()");
|
||||
}
|
||||
f.performDetach();
|
||||
if (!keepActive) {
|
||||
if (!f.mRetaining) {
|
||||
makeInactive(f);
|
||||
|
||||
Reference in New Issue
Block a user