web-dev-qa-db-ja.com

setRetainInstance(true)をさらに理解する

FragmentsetRetainInstance(true)を呼び出すとexactlyはどうなりますか?ドキュメントは事実上存在せず、これは非常に重要な機能のようです。具体的には、このシーケンス(私が作成した)がどれだけ正しいかを知りたいです。

  1. ユーザーがデバイスを回転させます。
  2. フラグメントはActivityから切り離され、Fragment.onDetach()が呼び出されます。
  3. アクティビティは破棄されます。 Activity.onDestroy()が呼び出されます。
  4. Activity Javaオブジェクトは削除されます(可能な場合、GCによって))。
  5. 新しいActivity Javaオブジェクトが作成され、そのコンストラクターとonCreate()が呼び出されます。
  6. Activity.onCreate()には、フラグメントを含むレイアウトを設定するsetContentView(...)があるか、FragmentTransactionを使用してフラグメントを追加します。
  7. 私はこれについて本当にわかりませんが、Androidは古いフラグメントを見つけるのに十分賢く、Fragment.onAttach()を呼び出して新しいActivity
  8. 次(または前?誰が知っていますか?)Activity.onResume()が呼び出されます。

それは正しいですか? Android賢く、最初にFragmentTransaction.add(new MyFragment(), ...)を明示的に使用しても、古いフラグメントを見つけるのに十分ですか?そして、そうであれば、anotheronCreate()のフラグメント?このようなことをする必要がありますか?:

    if (getSupportFragmentManager().findFragmentByTag("foo") == null)
    {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(new FooFragment(), "foo").commit();
    }
101
Timmmm

おそらく、私はAndroidのドキュメントに多少の過酷さを感じました。これは有用な情報を持っているためですが、残念ながらsetRetainInstance()からリンクされていません。)From フラグメントに関するページ

注:各フラグメントには、アクティビティが再開された場合にシステムがフラグメントの復元に使用できる一意の識別子が必要です(これを使用して、フラグメントを取り除いてトランザクションを実行することができます)。フラグメントのIDを提供するには、3つの方法があります。

  • Android:id属性に一意のIDを指定します。
  • Android:tag属性に一意の文字列を指定します。
  • 前の2つのどちらも指定しない場合、システムはコンテナビューのIDを使用します。

これは、setContentView(R.layout.whatever)Activity.onCreated()を実行し、そのレイアウトにsetRetainInstance(true)のフラグメントが含まれている場合、アクティビティが再作成されるときに、そのIDまたは鬼ごっこ。

第二に、UIのない​​フラグメントについては、

UIなしでフラグメントを追加するには、add(Fragment、String)を使用してアクティビティからフラグメントを追加します(ビューIDではなく、フラグメントに一意の文字列「タグ」を指定します)。これによりフラグメントが追加されますが、アクティビティレイアウト内のビューに関連付けられていないため、onCreateView()の呼び出しを受け取りません。したがって、そのメソッドを実装する必要はありません。

そして、ドキュメントは非常に良い例にリンクしています-FragmentRetainInstance.Javaこれはあなたの便宜のために以下に再現しました。私の質問の答えだと推測したとおりです(if (...findFragmentByTag() == null) { ...)。

最後に、独自のテストアクティビティを作成して、どの関数が呼び出されるかを正確に確認しました。縦向きで起動して横向きに回転すると、これが出力されます。コードは次のとおりです。

(これは読みやすくするために少し編集されています。)

TestActivity@415a4a30: this()
TestActivity@415a4a30: onCreate()
TestActivity@415a4a30: Existing fragment not found.
TestFragment{41583008}: this() TestFragment{41583008}
TestFragment{41583008}: onAttach(TestActivity@415a4a30)
TestFragment{41583008}: onCreate()
TestFragment{41583008}: onCreateView()
TestFragment{41583008}: onActivityCreated()
TestActivity@415a4a30: onStart()
TestFragment{41583008}: onStart()
TestActivity@415a4a30: onResume()
TestFragment{41583008}: onResume()

<rotate device>

TestFragment{41583008}: onPause()
TestActivity@415a4a30: onPause()
TestFragment{41583008}: onStop()
TestActivity@415a4a30: onStop()
TestFragment{41583008}: onDestroyView()
TestFragment{41583008}: onDetach()
TestActivity@415a4a30: onDestroy()
TestActivity@415a3380: this()
TestFragment{41583008}: onAttach(TestActivity@415a3380)
TestActivity@415a3380: onCreate()
TestActivity@415a3380: Existing fragment found.
TestFragment{41583008}: onCreateView()
TestFragment{41583008}: onActivityCreated()
TestActivity@415a3380: onStart()
TestFragment{41583008}: onStart()
TestActivity@415a3380: onResume()
TestFragment{41583008}: onResume()

Androidドキュメンテーションが間違っていることに注意してください:UIのない​​フラグメントdoesonCreateView()への呼び出しを受信しますが、 nullを自由に返すことができます。

TestActivity/TestFragmentのソースコード

import Android.app.Activity;
import Android.app.Fragment;
import Android.app.FragmentTransaction;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.TextView;

import com.concentriclivers.ss.R;

// An activity for understanding Android lifecycle events.
public class TestActivity extends Activity
{
    private static final String TAG = TestActivity.class.getSimpleName();

    public TestActivity()
    {
        super();
        Log.d(TAG, this + ": this()");
    }

    protected void finalize() throws Throwable
    {
        super.finalize();
        Log.d(TAG, this + ": finalize()");
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Log.d(TAG, this + ": onCreate()");


        TextView tv = new TextView(this);
        tv.setText("Hello world");
        setContentView(tv);

        if (getFragmentManager().findFragmentByTag("test_fragment") == null)
        {
            Log.d(TAG, this + ": Existing fragment not found.");
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.add(new TestFragment(), "test_fragment").commit();
        }
        else
        {
            Log.d(TAG, this + ": Existing fragment found.");
        }
    }

    @Override
    public void onStart()
    {
        super.onStart();
        Log.d(TAG, this + ": onStart()");
    }

    @Override
    public void onResume()
    {
        super.onResume();
        Log.d(TAG, this + ": onResume()");
    }

    @Override
    public void onPause()
    {
        super.onPause();
        Log.d(TAG, this + ": onPause()");
    }

    @Override
    public void onStop()
    {
        super.onStop();
        Log.d(TAG, this + ": onStop()");
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        Log.d(TAG, this + ": onDestroy()");
    }




    public static class TestFragment extends Fragment
    {
        private static final String TAG = TestFragment.class.getSimpleName();

        public TestFragment()
        {
            super();
            Log.d(TAG,  this + ": this() " + this);
        }

        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            Log.d(TAG, this + ": onCreate()");
            setRetainInstance(true);
        }

        @Override
        public void onAttach(final Activity activity)
        {
            super.onAttach(activity);
            Log.d(TAG, this + ": onAttach(" + activity + ")");
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState)
        {
            super.onActivityCreated(savedInstanceState);
            Log.d(TAG, this + ": onActivityCreated()");
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            Log.d(TAG, this + ": onCreateView()");
            return null;
        }

        @Override
        public void onViewCreated(View view, Bundle savedInstanceState)
        {
            super.onViewCreated(view, savedInstanceState);
            Log.d(TAG, this + ": onViewCreated()");
        }

        @Override
        public void onDestroyView()
        {
            super.onDestroyView();
            Log.d(TAG, this + ": onDestroyView()");
        }

        @Override
        public void onDetach()
        {
            super.onDetach();
            Log.d(TAG, this + ": onDetach()");
        }

        @Override
        public void onStart()
        {
            super.onStart();
            Log.d(TAG, this + ": onStart()");
        }

        @Override
        public void onResume()
        {
            super.onResume();
            Log.d(TAG, this + ": onResume()");
        }

        @Override
        public void onPause()
        {
            super.onPause();
            Log.d(TAG, this + ": onPause()");
        }

        @Override
        public void onStop()
        {
            super.onStop();
            Log.d(TAG, this + ": onStop()");
        }

        @Override
        public void onDestroy()
        {
            super.onDestroy();
            Log.d(TAG, this + ": onDestroy()");
        }
    }

}

FragmentRetainInstance.Javaのソースコード(API 16現在):

/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.Apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.Android.apis.app;

import com.example.Android.apis.R;

import Android.app.Activity;
import Android.app.Fragment;
import Android.app.FragmentManager;
import Android.os.Bundle;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.view.View.OnClickListener;
import Android.widget.Button;
import Android.widget.ProgressBar;

/**
 * This example shows how you can use a Fragment to easily propagate state
 * (such as threads) across activity instances when an activity needs to be
 * restarted due to, for example, a configuration change.  This is a lot
 * easier than using the raw Activity.onRetainNonConfiguratinInstance() API.
 */
public class FragmentRetainInstance extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // First time init, create the UI.
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction().add(Android.R.id.content,
                    new UiFragment()).commit();
        }
    }

    /**
     * This is a fragment showing UI that will be updated from work done
     * in the retained fragment.
     */
    public static class UiFragment extends Fragment {
        RetainedFragment mWorkFragment;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_retain_instance, container, false);

            // Watch for button clicks.
            Button button = (Button)v.findViewById(R.id.restart);
            button.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    mWorkFragment.restart();
                }
            });

            return v;
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            FragmentManager fm = getFragmentManager();

            // Check to see if we have retained the worker fragment.
            mWorkFragment = (RetainedFragment)fm.findFragmentByTag("work");

            // If not retained (or first time running), we need to create it.
            if (mWorkFragment == null) {
                mWorkFragment = new RetainedFragment();
                // Tell it who it is working with.
                mWorkFragment.setTargetFragment(this, 0);
                fm.beginTransaction().add(mWorkFragment, "work").commit();
            }
        }

    }

    /**
     * This is the Fragment implementation that will be retained across
     * activity instances.  It represents some ongoing work, here a thread
     * we have that sits around incrementing a progress indicator.
     */
    public static class RetainedFragment extends Fragment {
        ProgressBar mProgressBar;
        int mPosition;
        boolean mReady = false;
        boolean mQuiting = false;

        /**
         * This is the thread that will do our work.  It sits in a loop running
         * the progress up until it has reached the top, then stops and waits.
         */
        final Thread mThread = new Thread() {
            @Override
            public void run() {
                // We'll figure the real value out later.
                int max = 10000;

                // This thread runs almost forever.
                while (true) {

                    // Update our shared state with the UI.
                    synchronized (this) {
                        // Our thread is stopped if the UI is not ready
                        // or it has completed its work.
                        while (!mReady || mPosition >= max) {
                            if (mQuiting) {
                                return;
                            }
                            try {
                                wait();
                            } catch (InterruptedException e) {
                            }
                        }

                        // Now update the progress.  Note it is important that
                        // we touch the progress bar with the lock held, so it
                        // doesn't disappear on us.
                        mPosition++;
                        max = mProgressBar.getMax();
                        mProgressBar.setProgress(mPosition);
                    }

                    // Normally we would be doing some work, but put a kludge
                    // here to pretend like we are.
                    synchronized (this) {
                        try {
                            wait(50);
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }
        };

        /**
         * Fragment initialization.  We way we want to be retained and
         * start our thread.
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Tell the framework to try to keep this fragment around
            // during a configuration change.
            setRetainInstance(true);

            // Start up the worker thread.
            mThread.start();
        }

        /**
         * This is called when the Fragment's Activity is ready to go, after
         * its content view has been installed; it is called both after
         * the initial fragment creation and after the fragment is re-attached
         * to a new activity.
         */
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            // Retrieve the progress bar from the target's view hierarchy.
            mProgressBar = (ProgressBar)getTargetFragment().getView().findViewById(
                    R.id.progress_horizontal);

            // We are ready for our thread to go.
            synchronized (mThread) {
                mReady = true;
                mThread.notify();
            }
        }

        /**
         * This is called when the fragment is going away.  It is NOT called
         * when the fragment is being propagated between activity instances.
         */
        @Override
        public void onDestroy() {
            // Make the thread go away.
            synchronized (mThread) {
                mReady = false;
                mQuiting = true;
                mThread.notify();
            }

            super.onDestroy();
        }

        /**
         * This is called right before the fragment is detached from its
         * current activity instance.
         */
        @Override
        public void onDetach() {
            // This fragment is being detached from its activity.  We need
            // to make sure its thread is not going to touch any activity
            // state after returning from this function.
            synchronized (mThread) {
                mProgressBar = null;
                mReady = false;
                mThread.notify();
            }

            super.onDetach();
        }

        /**
         * API for our UI to restart the progress thread.
         */
        public void restart() {
            synchronized (mThread) {
                mPosition = 0;
                mThread.notify();
            }
        }
    }
}
90
Timmmm

FragmentクラスのsetRetainInstance()は、ActivityクラスなどのonRetainCustomNonConfigurationInstance()の賢い代替品です。

明確に述べられている ドキュメントで

発生したログ(UIフラグメントがオンデマンドで追加され、次に設定が変更されます):

デフォルトのsetRetainInstance(false)

_09-29 13:23:04.771: DEBUG/szipinf(4790): Initializing inflate state
09-29 13:23:04.801: INFO/TESTING - MYACTIVITY(4790): Instantiated - com.example.MyActivity@405196b0
09-29 13:23:04.851: DEBUG/dalvikvm(4790): GC_EXTERNAL_ALLOC freed 49K, 51% free 2686K/5379K, external 0K/0K, paused 45ms
09-29 13:23:04.881: INFO/TESTING - MYACTIVITY(4790): onCreate - com.example.MyActivity@405196b0
09-29 13:23:04.881: INFO/TESTING - MYACTIVITY(4790): onStart - com.example.MyActivity@405196b0
09-29 13:23:04.881: INFO/TESTING - MYACTIVITY(4790): onResume - com.example.MyActivity@405196b0
09-29 13:23:04.891: INFO/TESTING - MYACTIVITY(4790): onAttachedToWindow - com.example.MyActivity@405196b0
09-29 13:23:10.381: DEBUG/dalvikvm(4457): GC_EXPLICIT freed 8K, 51% free 2681K/5379K, external 0K/0K, paused 38ms
09-29 13:23:11.901: INFO/TESTING - MYFRAGMENT(4790): Instantiated - MyFragment{40530610}
09-29 13:23:11.911: INFO/TESTING - MYFRAGMENT(4790): onAttach - MyFragment{40530610 #0 MyFragment}
09-29 13:23:11.911: INFO/TESTING - MYACTIVITY(4790): onAttachFragment - com.example.MyActivity@405196b0
09-29 13:23:11.911: INFO/TESTING - MYFRAGMENT(4790): onCreate - MyFragment{40530610 #0 MyFragment}
09-29 13:23:11.911: INFO/TESTING - MYFRAGMENT(4790): onCreateView - MyFragment{40530610 #0 MyFragment}
09-29 13:23:11.921: INFO/TESTING - MYFRAGMENT(4790): onViewCreated - MyFragment{40530610 #0 MyFragment}
09-29 13:23:11.921: INFO/TESTING - MYFRAGMENT(4790): onActivityCreated - MyFragment{40530610 #0 MyFragment}
09-29 13:23:11.931: INFO/TESTING - MYFRAGMENT(4790): onStart - MyFragment{40530610 #0 MyFragment}
09-29 13:23:11.931: INFO/TESTING - MYFRAGMENT(4790): onResume - MyFragment{40530610 #0 MyFragment}
09-29 13:23:15.081: INFO/ActivityManager(1268): Config changed: { scale=1.0 imsi=404/45 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=105 themeResource=null}
09-29 13:23:15.111: INFO/TESTING - MYACTIVITY(4790): onSaveInstanceState - com.example.MyActivity@405196b0
09-29 13:23:15.111: INFO/TESTING - MYFRAGMENT(4790): onPause - MyFragment{40530610 #0 MyFragment}
09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onPause - com.example.MyActivity@405196b0
09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onStop - MyFragment{40530610 #0 MyFragment}
09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onStop - com.example.MyActivity@405196b0
09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onRetainCustomNonConfigurationInstance - com.example.MyActivity@405196b0
09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onDestroyView - MyFragment{40530610 #0 MyFragment}
09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onDestroy - MyFragment{40530610 #0 MyFragment}
09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onDetach - MyFragment{40530610 #0 MyFragment}
09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onDestroy - com.example.MyActivity@405196b0
09-29 13:23:15.191: INFO/TESTING - MYACTIVITY(4790): onDetachedFromWindow - com.example.MyActivity@405196b0
09-29 13:23:15.201: INFO/TESTING - MYACTIVITY(4790): Instantiated - com.example.MyActivity@4053c438
09-29 13:23:15.201: INFO/TESTING - MYFRAGMENT(4790): Instantiated - MyFragment{4053cde0}
09-29 13:23:15.201: INFO/TESTING - MYFRAGMENT(4790): onAttach - MyFragment{4053cde0 #0 MyFragment}
09-29 13:23:15.201: INFO/TESTING - MYACTIVITY(4790): onAttachFragment - com.example.MyActivity@4053c438
09-29 13:23:15.201: INFO/TESTING - MYFRAGMENT(4790): onCreate - MyFragment{4053cde0 #0 MyFragment}
09-29 13:23:15.251: INFO/TESTING - MYACTIVITY(4790): onCreate - com.example.MyActivity@4053c438
09-29 13:23:15.251: INFO/TESTING - MYFRAGMENT(4790): onCreateView - MyFragment{4053cde0 #0 MyFragment}
09-29 13:23:15.261: INFO/TESTING - MYFRAGMENT(4790): onViewCreated - MyFragment{4053cde0 #0 MyFragment}
09-29 13:23:15.261: INFO/TESTING - MYFRAGMENT(4790): onActivityCreated - MyFragment{4053cde0 #0 MyFragment}
09-29 13:23:15.291: INFO/TESTING - MYFRAGMENT(4790): onStart - MyFragment{4053cde0 #0 MyFragment}
09-29 13:23:15.291: INFO/TESTING - MYACTIVITY(4790): onStart - com.example.MyActivity@4053c438
09-29 13:23:15.291: INFO/TESTING - MYACTIVITY(4790): onResume - com.example.MyActivity@4053c438
09-29 13:23:15.291: INFO/TESTING - MYFRAGMENT(4790): onResume - MyFragment{4053cde0 #0 MyFragment}
09-29 13:23:15.321: INFO/TESTING - MYACTIVITY(4790): onAttachedToWindow - com.example.MyActivity@4053c438
_

したがって、フラグメントはまったく新しいものとして再作成され、再び表示されますが、これはすべてsetRetainInstance(false)

そして今ではsetRetainInstance(true)

_09-29 13:18:46.121: INFO/ActivityManager(1268): Starting: Intent { flg=0x10100000 cmp=com.example/.MyActivity } from pid 1268
09-29 13:18:46.141: INFO/TESTING - MYACTIVITY(4726): Instantiated - com.example.MyActivity@4056f2e0
09-29 13:18:46.161: INFO/TESTING - MYACTIVITY(4726): onCreate - com.example.MyActivity@4056f2e0
09-29 13:18:46.161: INFO/TESTING - MYACTIVITY(4726): onStart - com.example.MyActivity@4056f2e0
09-29 13:18:46.161: INFO/TESTING - MYACTIVITY(4726): onResume - com.example.MyActivity@4056f2e0
09-29 13:18:46.191: INFO/TESTING - MYACTIVITY(4726): onAttachedToWindow - com.example.MyActivity@4056f2e0
09-29 13:19:10.431: DEBUG/SntpClient(1268): request time failed: Java.net.UnknownHostException: europe.pool.ntp.org
09-29 13:19:14.251: INFO/TESTING - MYFRAGMENT(4726): Instantiated - MyFragment{405288c0}
09-29 13:19:14.271: INFO/TESTING - MYFRAGMENT(4726): onAttach - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:14.271: INFO/TESTING - MYACTIVITY(4726): onAttachFragment - com.example.MyActivity@4056f2e0
09-29 13:19:14.271: INFO/TESTING - MYFRAGMENT(4726): onCreate - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:14.281: INFO/TESTING - MYFRAGMENT(4726): onCreateView - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:14.281: INFO/TESTING - MYFRAGMENT(4726): onViewCreated - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:14.281: INFO/TESTING - MYFRAGMENT(4726): onActivityCreated - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:14.291: INFO/TESTING - MYFRAGMENT(4726): onStart - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:14.291: INFO/TESTING - MYFRAGMENT(4726): onResume - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:21.921: INFO/ActivityManager(1268): Config changed: { scale=1.0 imsi=404/45 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=103 themeResource=null}
09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onSaveInstanceState - com.example.MyActivity@4056f2e0
09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onPause - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onPause - com.example.MyActivity@4056f2e0
09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onStop - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onStop - com.example.MyActivity@4056f2e0
09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onRetainCustomNonConfigurationInstance - com.example.MyActivity@4056f2e0
09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onDestroyView - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onDetach - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onDestroy - com.example.MyActivity@4056f2e0
09-29 13:19:22.111: INFO/TESTING - MYACTIVITY(4726): onDetachedFromWindow - com.example.MyActivity@4056f2e0
09-29 13:19:22.111: INFO/TESTING - MYACTIVITY(4726): Instantiated - com.example.MyActivity@4054a0e8
09-29 13:19:22.111: INFO/TESTING - MYFRAGMENT(4726): onAttach - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.111: INFO/TESTING - MYACTIVITY(4726): onAttachFragment - com.example.MyActivity@4054a0e8
09-29 13:19:22.131: INFO/TESTING - MYACTIVITY(4726): onCreate - com.example.MyActivity@4054a0e8
09-29 13:19:22.131: INFO/TESTING - MYFRAGMENT(4726): onCreateView - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.131: INFO/TESTING - MYFRAGMENT(4726): onViewCreated - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.131: INFO/TESTING - MYFRAGMENT(4726): onActivityCreated - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.141: INFO/TESTING - MYFRAGMENT(4726): onStart - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.141: INFO/TESTING - MYACTIVITY(4726): onStart - com.example.MyActivity@4054a0e8
09-29 13:19:22.141: INFO/TESTING - MYACTIVITY(4726): onResume - com.example.MyActivity@4054a0e8
09-29 13:19:22.141: INFO/TESTING - MYFRAGMENT(4726): onResume - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.171: INFO/TESTING - MYACTIVITY(4726): onAttachedToWindow - com.example.MyActivity@4054a0e8
09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onPause - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onStop - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onDestroyView - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onDestroy - MyFragment{405288c0 #0 MyFragment}
09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onDetach - MyFragment{405288c0 #0 MyFragment}
_

効果に気づいた?フラグメントインスタンス(オブジェクト405288c0)は保持されましたが、これは良好です。ただし、保持されたインスタンスは、以前の方向に属していたリソースとビューおよびオブジェクトを保持する可能性が非常に高く、これによりメモリリークが発生する可能性があります。

このフラグメントを開始するコードを記述する場所にはさらに注意する必要があります。常に既存のインスタンスを確認する必要があります。

ストーリーの教訓:setRetainInstance()は、視覚的でない断片に最適です。

42
S.D.