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

Commit 625ac271 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Work on fragments in layouts.

- Change semantics if IDs associated with these fragments, to
  work correctly when placed in a container.  If the container
  has an ID or you have supplied a tag, the fragment's ID is
  optional.

- To do this, there is a new LayoutInflater API that allows code
  creating views to access the parent container that view will
  be in.

- Fix issues with state management around these fragments.  Now
  correctly retains state when switching to a layout that doesn't
  include the fragment.

Also:

- Add new simple list layouts for items that want to show an
  activated state.
- Add new Activity.dump() that can be invoked with adb shell
  dumpsys; the default implementation dumps fragment state.

Change-Id: I192f35e3ea8c53fbd26cf909095f2a994abfc1b6
parent 6cf08937
Loading
Loading
Loading
Loading
+180 −1
Original line number Diff line number Diff line
@@ -15869,6 +15869,28 @@
 visibility="public"
>
</field>
<field name="simple_list_item_activated_1"
 type="int"
 transient="false"
 volatile="false"
 value="17367075"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="simple_list_item_activated_2"
 type="int"
 transient="false"
 volatile="false"
 value="17367076"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="simple_list_item_checked"
 type="int"
 transient="false"
@@ -22618,7 +22640,7 @@
</implements>
<implements name="android.view.KeyEvent.Callback">
</implements>
<implements name="android.view.LayoutInflater.Factory">
<implements name="android.view.LayoutInflater.Factory2">
</implements>
<implements name="android.view.View.OnCreateContextMenuListener">
</implements>
@@ -22751,6 +22773,23 @@
<parameter name="ev" type="android.view.MotionEvent">
</parameter>
</method>
<method name="dump"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="fd" type="java.io.FileDescriptor">
</parameter>
<parameter name="writer" type="java.io.PrintWriter">
</parameter>
<parameter name="args" type="java.lang.String[]">
</parameter>
</method>
<method name="findFragmentById"
 return="android.app.Fragment"
 abstract="false"
@@ -23456,6 +23495,25 @@
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
</method>
<method name="onCreateView"
 return="android.view.View"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="parent" type="android.view.View">
</parameter>
<parameter name="name" type="java.lang.String">
</parameter>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
</method>
<method name="onDestroy"
 return="void"
 abstract="false"
@@ -28720,6 +28778,25 @@
 visibility="public"
>
</constructor>
<method name="dump"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="prefix" type="java.lang.String">
</parameter>
<parameter name="fd" type="java.io.FileDescriptor">
</parameter>
<parameter name="writer" type="java.io.PrintWriter">
</parameter>
<parameter name="args" type="java.lang.String[]">
</parameter>
</method>
<method name="equals"
 return="boolean"
 abstract="false"
@@ -28908,6 +28985,17 @@
 visibility="public"
>
</method>
<method name="isInLayout"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="isResumed"
 return="boolean"
 abstract="false"
@@ -29514,6 +29602,25 @@
 visibility="public"
>
</method>
<method name="dump"
 return="void"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="prefix" type="java.lang.String">
</parameter>
<parameter name="fd" type="java.io.FileDescriptor">
</parameter>
<parameter name="writer" type="java.io.PrintWriter">
</parameter>
<parameter name="args" type="java.lang.String[]">
</parameter>
</method>
<method name="findFragmentById"
 return="android.app.Fragment"
 abstract="true"
@@ -193168,6 +193275,17 @@
 visibility="public"
>
</method>
<method name="getFactory2"
 return="android.view.LayoutInflater.Factory2"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getFilter"
 return="android.view.LayoutInflater.Filter"
 abstract="false"
@@ -193260,6 +193378,25 @@
<exception name="ClassNotFoundException" type="java.lang.ClassNotFoundException">
</exception>
</method>
<method name="onCreateView"
 return="android.view.View"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="protected"
>
<parameter name="parent" type="android.view.View">
</parameter>
<parameter name="name" type="java.lang.String">
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
<exception name="ClassNotFoundException" type="java.lang.ClassNotFoundException">
</exception>
</method>
<method name="setFactory"
 return="void"
 abstract="false"
@@ -193273,6 +193410,19 @@
<parameter name="factory" type="android.view.LayoutInflater.Factory">
</parameter>
</method>
<method name="setFactory2"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="factory" type="android.view.LayoutInflater.Factory2">
</parameter>
</method>
<method name="setFilter"
 return="void"
 abstract="false"
@@ -193312,6 +193462,35 @@
</parameter>
</method>
</interface>
<interface name="LayoutInflater.Factory2"
 abstract="true"
 static="true"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<implements name="android.view.LayoutInflater.Factory">
</implements>
<method name="onCreateView"
 return="android.view.View"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="parent" type="android.view.View">
</parameter>
<parameter name="name" type="java.lang.String">
</parameter>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
</method>
</interface>
<interface name="LayoutInflater.Filter"
 abstract="true"
 static="true"
+70 −12
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
import android.widget.FrameLayout;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;

@@ -605,7 +607,7 @@ import java.util.HashMap;
 * or finished.
 */
public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory,
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks {
    private static final String TAG = "Activity";
@@ -4030,15 +4032,30 @@ public class Activity extends ContextThemeWrapper
     * Standard implementation of
     * {@link android.view.LayoutInflater.Factory#onCreateView} used when
     * inflating with the LayoutInflater returned by {@link #getSystemService}.
     * This implementation does nothing and is for
     * pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} apps.  Newer apps
     * should use {@link #onCreateView(View, String, Context, AttributeSet)}.
     *
     * @see android.view.LayoutInflater#createView
     * @see android.view.Window#getLayoutInflater
     */
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        return null;
    }

    /**
     * Standard implementation of
     * {@link android.view.LayoutInflater.Factory2#onCreateView(View, String, Context, AttributeSet)}
     * used when inflating with the LayoutInflater returned by {@link #getSystemService}.
     * This implementation handles <fragment> tags to embed fragments inside
     * of the activity.
     *
     * @see android.view.LayoutInflater#createView
     * @see android.view.Window#getLayoutInflater
     */
    public View onCreateView(String name, Context context, AttributeSet attrs) {
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        if (!"fragment".equals(name)) {
            return null;
            return onCreateView(name, context, attrs);
        }
        
        String fname = attrs.getAttributeValue(null, "class");
@@ -4047,48 +4064,89 @@ public class Activity extends ContextThemeWrapper
        if (fname == null) {
            fname = a.getString(com.android.internal.R.styleable.Fragment_name);
        }
        int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, 0);
        int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, View.NO_ID);
        String tag = a.getString(com.android.internal.R.styleable.Fragment_tag);
        a.recycle();
        
        if (id == 0) {
        int containerId = parent != null ? parent.getId() : 0;
        if (containerId == View.NO_ID && id == View.NO_ID && tag == null) {
            throw new IllegalArgumentException(attrs.getPositionDescription()
                    + ": Must specify unique android:id for " + fname);
                    + ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname);
        }

        // 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);
        Fragment fragment = id != View.NO_ID ? mFragments.findFragmentById(id) : null;
        if (fragment == null && tag != null) {
            fragment = mFragments.findFragmentByTag(tag);
        }
        if (fragment == null && containerId != View.NO_ID) {
            fragment = mFragments.findFragmentById(containerId);
        }

        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x"
                + Integer.toHexString(id) + " fname=" + fname
                + " existing=" + fragment);
        if (fragment == null) {
            fragment = Fragment.instantiate(this, fname);
            fragment.mFromLayout = true;
            fragment.mFragmentId = id;
            fragment.mFragmentId = id != 0 ? id : containerId;
            fragment.mContainerId = containerId;
            fragment.mTag = tag;
            fragment.mInLayout = true;
            fragment.mImmediateActivity = this;
            fragment.mFragmentManager = mFragments;
            fragment.onInflate(attrs, fragment.mSavedFragmentState);
            mFragments.addFragment(fragment, true);

        } else if (fragment.mInLayout) {
            // A fragment already exists and it is not one we restored from
            // previous state.
            throw new IllegalArgumentException(attrs.getPositionDescription()
                    + ": Duplicate id 0x" + Integer.toHexString(id)
                    + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId)
                    + " with another fragment for " + fname);
        } else {
            // This fragment was retained from a previous instance; get it
            // going now.
            fragment.mInLayout = true;
            fragment.mImmediateActivity = this;
            // 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(attrs, fragment.mSavedFragmentState);
            }
            mFragments.addFragment(fragment, true);
            mFragments.moveToState(fragment);
        }

        if (fragment.mView == null) {
            throw new IllegalStateException("Fragment " + fname
                    + " did not create a view.");
        }
        if (id != 0) {
            fragment.mView.setId(id);
        }
        if (fragment.mView.getTag() == null) {
            fragment.mView.setTag(tag);
        }
        return fragment.mView;
    }

    /**
     * Print the Activity's state into the given stream.  This gets invoked if
     * you run "adb shell dumpsys activity <youractivityname>".
     *
     * @param fd The raw file descriptor that the dump is being sent to.
     * @param writer The PrintWriter to which you should dump your state.  This will be
     * closed for you after you return.
     * @param args additional arguments to the dump request.
     */
    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        mFragments.dump("", fd, writer, args);
    }

    /**
     * Bit indicating that this activity is "immersive" and should not be
     * interrupted by notifications if possible.
@@ -4177,7 +4235,7 @@ public class Activity extends ContextThemeWrapper
        
        mWindow = PolicyManager.makeNewWindow(this);
        mWindow.setCallback(this);
        mWindow.getLayoutInflater().setFactory(this);
        mWindow.getLayoutInflater().setFactory2(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
+47 −7
Original line number Diff line number Diff line
@@ -335,9 +335,9 @@ public final class ActivityThread {
        }
    }

    private static final class DumpServiceInfo {
    private static final class DumpComponentInfo {
        FileDescriptor fd;
        IBinder service;
        IBinder token;
        String[] args;
        boolean dumped;
    }
@@ -592,9 +592,9 @@ public final class ActivityThread {
        }

        public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
            DumpServiceInfo data = new DumpServiceInfo();
            DumpComponentInfo data = new DumpComponentInfo();
            data.fd = fd;
            data.service = servicetoken;
            data.token = servicetoken;
            data.args = args;
            data.dumped = false;
            queueOrSendMessage(H.DUMP_SERVICE, data);
@@ -665,6 +665,25 @@ public final class ActivityThread {
            queueOrSendMessage(H.SCHEDULE_CRASH, msg);
        }

        public void dumpActivity(FileDescriptor fd, IBinder activitytoken, String[] args) {
            DumpComponentInfo data = new DumpComponentInfo();
            data.fd = fd;
            data.token = activitytoken;
            data.args = args;
            data.dumped = false;
            queueOrSendMessage(H.DUMP_ACTIVITY, data);
            synchronized (data) {
                while (!data.dumped) {
                    try {
                        data.wait();
                    } catch (InterruptedException e) {
                        // no need to do anything here, we will keep waiting until
                        // dumped is set
                    }
                }
            }
        }
        
        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            long nativeMax = Debug.getNativeHeapSize() / 1024;
@@ -892,6 +911,7 @@ public final class ActivityThread {
        public static final int DISPATCH_PACKAGE_BROADCAST = 133;
        public static final int SCHEDULE_CRASH          = 134;
        public static final int DUMP_HEAP               = 135;
        public static final int DUMP_ACTIVITY           = 136;
        String codeToString(int code) {
            if (localLOGV) {
                switch (code) {
@@ -931,6 +951,7 @@ public final class ActivityThread {
                    case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
                    case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
                    case DUMP_HEAP: return "DUMP_HEAP";
                    case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
                }
            }
            return "(unknown)";
@@ -1025,7 +1046,7 @@ public final class ActivityThread {
                    scheduleGcIdler();
                    break;
                case DUMP_SERVICE:
                    handleDumpService((DumpServiceInfo)msg.obj);
                    handleDumpService((DumpComponentInfo)msg.obj);
                    break;
                case LOW_MEMORY:
                    handleLowMemory();
@@ -1059,6 +1080,9 @@ public final class ActivityThread {
                case DUMP_HEAP:
                    handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
                    break;
                case DUMP_ACTIVITY:
                    handleDumpActivity((DumpComponentInfo)msg.obj);
                    break;
            }
        }

@@ -2024,9 +2048,9 @@ public final class ActivityThread {
        }
    }

    private void handleDumpService(DumpServiceInfo info) {
    private void handleDumpService(DumpComponentInfo info) {
        try {
            Service s = mServices.get(info.service);
            Service s = mServices.get(info.token);
            if (s != null) {
                PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd));
                s.dump(info.fd, pw, info.args);
@@ -2040,6 +2064,22 @@ public final class ActivityThread {
        }
    }

    private void handleDumpActivity(DumpComponentInfo info) {
        try {
            ActivityClientRecord r = mActivities.get(info.token);
            if (r != null && r.activity != null) {
                PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd));
                r.activity.dump(info.fd, pw, info.args);
                pw.close();
            }
        } finally {
            synchronized (info) {
                info.dumped = true;
                info.notifyAll();
            }
        }
    }

    private final void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
+26 −0
Original line number Diff line number Diff line
@@ -414,6 +414,21 @@ public abstract class ApplicationThreadNative extends Binder
            dumpHeap(managed, path, fd);
            return true;
        }

        case DUMP_ACTIVITY_TRANSACTION: {
            data.enforceInterface(IApplicationThread.descriptor);
            ParcelFileDescriptor fd = data.readFileDescriptor();
            final IBinder activity = data.readStrongBinder();
            final String[] args = data.readStringArray();
            if (fd != null) {
                dumpActivity(fd.getFileDescriptor(), activity, args);
                try {
                    fd.close();
                } catch (IOException e) {
                }
            }
            return true;
        }
        }

        return super.onTransact(code, data, reply, flags);
@@ -857,5 +872,16 @@ class ApplicationThreadProxy implements IApplicationThread {
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }

    public void dumpActivity(FileDescriptor fd, IBinder token, String[] args)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeFileDescriptor(fd);
        data.writeStrongBinder(token);
        data.writeStringArray(args);
        mRemote.transact(DUMP_ACTIVITY_TRANSACTION, data, null, 0);
        data.recycle();
    }
}
+115 −2
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;

final class FragmentState implements Parcelable {
@@ -207,7 +209,7 @@ final class FragmentState implements Parcelable {
 *
 * <p>An activity's layout XML can include <code>&lt;fragment&gt;</code> tags
 * to embed fragment instances inside of the layout.  For example, here is
 * a simply layout that embeds one fragment:</p>
 * a simple layout that embeds one fragment:</p>
 *
 * {@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout}
 *
@@ -251,6 +253,33 @@ final class FragmentState implements Parcelable {
 * details activity will finish of it finds itself running in a configuration
 * where the details can be shown inline.
 *
 * <p>When a configuration change causes the activity hosting these fragments
 * to restart, its new instance may use a different layout that doesn't
 * include the same fragments as the previous layout.  In this case all of
 * the previous fragments will still be instantiated and running in the new
 * instance; however, any that are no longer associated with a &lt;fragment&gt;
 * tag in the view hierarchy will not have their content view created and will
 * return false from {@link #isInLayout}.
 * 
 * <p>The attributes of the &lt;fragment&gt; tag are used to control the
 * LayoutParams provider when attaching the fragment's view to the parent
 * container.  They can alse be parsed by the fragment in {@link #onInflate}
 * as parameters.
 * 
 * <p>The fragment being instantiated must have some kind of unique identifier
 * so that it can be re-associated with a previous instance if the parent
 * activity needs to be destroyed and recreated.  This can be provided these
 * ways:
 * 
 * <ul>
 * <li>If nothing is explicitly supplied, the view ID of the container will
 * be used.
 * <li><code>android:tag</code> can be used in &lt;fragment&gt; to provide
 * a specific tag name for the fragment.
 * <li><code>android:id</code> can be used in &lt;fragment&gt; to provide
 * a specific identifier for the fragment.
 * </ul>
 * 
 * <a name="BackStack"></a>
 * <h3>Back Stack</h3>
 *
@@ -316,6 +345,9 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
    // Set to true if this fragment was instantiated from a layout file.
    boolean mFromLayout;
    
    // Set to true when the view has actually been inflated in its layout.
    boolean mInLayout;

    // Number of active back stack entries this fragment is in.
    int mBackStackNesting;
    
@@ -585,7 +617,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
    /**
     * Return the FragmentManager for interacting with fragments associated
     * with this fragment's activity.  Note that this will be non-null slightly
     * before {@link #getActivity()}, in the time from when the fragment is
     * 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.
     */
@@ -600,6 +632,17 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
        return mActivity != null && mActivity.mFragments.mAdded.contains(this);
    }
    
    /**
     * Return true if the layout is included as part of an activity view
     * hierarchy via the &lt;fragment&gt; tag.  This will always be true when
     * fragments are created through the &lt;fragment&gt; tag, <em>except</em>
     * in the case where an old fragment is restored from a previous state and
     * it does not appear in the layout of the current state.
     */
    final public boolean isInLayout() {
        return mInLayout;
    }

    /**
     * Return true if the fragment is in the resumed state.  This is true
     * for the duration of {@link #onResume()} and {@link #onPause()} as well.
@@ -1075,6 +1118,76 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
        return false;
    }
    
    /**
     * Print the Fragments's state into the given stream.
     *
     * @param prefix Text to print at the front of each line.
     * @param fd The raw file descriptor that the dump is being sent to.
     * @param writer The PrintWriter to which you should dump your state.  This will be
     * closed for you after you return.
     * @param args additional arguments to the dump request.
     */
    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
        writer.print(prefix); writer.print("mFragmentId="); writer.print(mFragmentId);
                writer.print(" mContainerId="); writer.print(mContainerId);
                writer.print(" mTag="); writer.println(mTag);
        writer.print(prefix); writer.print("mState="); writer.print(mState);
                writer.print(" mIndex="); writer.print(mIndex);
                writer.print(" mWho="); writer.print(mWho);
                writer.print(" mBackStackNesting="); writer.println(mBackStackNesting);
        writer.print(prefix); writer.print("mAdded="); writer.print(mAdded);
                writer.print(" mResumed="); writer.print(mResumed);
                writer.print(" mFromLayout="); writer.print(mFromLayout);
                writer.print(" mInLayout="); writer.println(mInLayout);
        writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
                writer.print(" mRetainInstance="); writer.print(mRetainInstance);
                writer.print(" mRetaining="); writer.print(mRetaining);
                writer.print(" mHasMenu="); writer.println(mHasMenu);
        if (mFragmentManager != null) {
            writer.print(prefix); writer.print("mFragmentManager=");
                    writer.println(mFragmentManager);
        }
        if (mImmediateActivity != null) {
            writer.print(prefix); writer.print("mImmediateActivity=");
                    writer.println(mImmediateActivity);
        }
        if (mActivity != null) {
            writer.print(prefix); writer.print("mActivity=");
                    writer.println(mActivity);
        }
        if (mArguments != null) {
            writer.print(prefix); writer.print("mArguments="); writer.println(mArguments);
        }
        if (mSavedFragmentState != null) {
            writer.print(prefix); writer.print("mSavedFragmentState=");
                    writer.println(mSavedFragmentState);
        }
        if (mSavedViewState != null) {
            writer.print(prefix); writer.print("mSavedViewState=");
                    writer.println(mSavedViewState);
        }
        if (mTarget != null) {
            writer.print(prefix); writer.print("mTarget="); writer.print(mTarget);
                    writer.print(" mTargetRequestCode=");
                    writer.println(mTargetRequestCode);
        }
        if (mNextAnim != 0) {
            writer.print(prefix); writer.print("mNextAnim="); writer.println(mNextAnim);
        }
        if (mContainer != null) {
            writer.print(prefix); writer.print("mContainer="); writer.println(mContainer);
        }
        if (mView != null) {
            writer.print(prefix); writer.print("mView="); writer.println(mView);
        }
        if (mLoaderManager != null) {
            writer.print(prefix); writer.print("mLoaderManager="); writer.print(mLoaderManager);
                    writer.print(" mStarted="); writer.print(mStarted);
                    writer.print(" mCheckedForLoaderManager=");
                    writer.println(mCheckedForLoaderManager);
        }
    }

    void performStop() {
        onStop();
        if (mStarted) {
Loading