Android:使用支持片段管理器时复制片段

Bhi*_*fer 12 lifecycle android fragment android-lifecycle android-activity

片段有一个非常奇怪的问题.我使用最新的支持库.我也使用Google在其IOSCHED项目中使用的类似代码

但是我在轮换后重新创建活动时遇到问题.在销毁并再次创建活动之后,我调用了用于管理片段事务的方法(在onStart方法中).这行只被调用一次,但它创建片段TWICE!

这是我的活动方法:

public abstract class SinglePaneActivity extends FragmentActivity
{
    @Override
    protected void onStart()
    {
        super.onStart();

        if(mFragment == null)
        {
            mFragment = onCreatePane();     
            mFragment.setArguments(Utils.intentToFragmentArguments(getIntent()));

            Log.w(TAG, "Fragment creation counter = " + createCounter);
            createCounter++;

            getSupportFragmentManager() 
            .beginTransaction()
            .add(R.id.root_container,mFragment)
            .commit();
        }
    }

    @Override
    protected void onStop()
    {
        Log.i(TAG, "onStop");
        if(mFragment != null)
        {
            getSupportFragmentManager()
            .beginTransaction()
            .remove(mFragment)
            .commit();

            mFragment = null;
        }
        super.onStop();
    }
}
Run Code Online (Sandbox Code Playgroud)

和我的日志:

--Start of application--
11-18 13:26:37.050: I/SinglePaneActivity(19040): onCreate
11-18 13:26:37.050: I/SinglePaneActivity(19040): onStart
11-18 13:26:37.055: W/SinglePaneActivity(19040): replacing fragment, counter = 1
11-18 13:26:37.075: I/MyFragment(19040): onCreate
11-18 13:26:37.110: I/MyFragment(19040): onActivityCreated
--Rotating the device--
11-18 13:26:39.600: I/SinglePaneActivity(19040): onStop
11-18 13:26:39.600: I/SinglePaneActivity(19040): onDestroy
11-18 13:26:39.605: I/MyFragment(19040): onDestroy
11-18 13:26:39.755: I/MyFragment(19040): onCreate
11-18 13:26:39.755: I/SinglePaneActivity(19040): onCreate
11-18 13:26:39.790: I/MyFragment(19040): onActivityCreated
11-18 13:26:39.800: I/SinglePaneActivity(19040): onStart
11-18 13:26:39.800: W/SinglePaneActivity(19040): replacing fragment, counter = 2
11-18 13:26:39.810: I/MyFragment(19040): onCreate
11-18 13:26:39.815: I/MyFragment(19040): onActivityCreated
--Rotating the device back--
11-18 13:36:47.060: I/SinglePaneActivity(19040): onStop
11-18 13:36:47.060: I/SinglePaneActivity(19040): onDestroy
11-18 13:36:47.060: I/MyFragment(19040): onDestroy
11-18 13:36:47.065: I/MyFragment(19040): onDestroy
11-18 13:36:47.130: I/MyFragment(19040): onCreate
11-18 13:36:47.130: I/MyFragment(19040): onCreate
11-18 13:36:47.130: I/SinglePaneActivity(19040): onCreate
11-18 13:36:47.140: I/MyFragment(19040): onActivityCreated
11-18 13:36:47.150: I/MyFragment(19040): onActivityCreated
11-18 13:36:47.150: I/SinglePaneActivity(19040): onStart
11-18 13:36:47.150: W/SinglePaneActivity(19040): replacing fragment, counter = 3
11-18 13:36:47.160: I/MyFragment(19040): onCreate
11-18 13:36:47.160: I/MyFragment(19040): onActivityCreated
--Exiting the app--
11-18 13:36:48.880: I/SinglePaneActivity(19040): onStop
11-18 13:36:48.885: I/SinglePaneActivity(19040): onDestroy
11-18 13:36:48.885: I/MyFragment(19040): onDestroy
11-18 13:36:48.890: I/MyFragment(19040): onDestroy
11-18 13:36:48.890: I/MyFragment(19040): onDestroy
Run Code Online (Sandbox Code Playgroud)

因此,每次旋转后碎片的数量都在增加.

在旋转之后,它会在进入我的onStart方法之前恢复片段,而我的onStart方法在同一个Frame布局容器中创建第二个相同的片段.但它在哪里恢复第一个片段?我想要它.或者我应该更改我的"if"以测试它是否已经创建?但我不知道如何确定它.看起来null测试是无用的.

我还通过替换add()方法做了一个小的解决方法replace().在此之后,片段的数量不会增长,并且每个片段在onStart创建新方法之前被销毁.但是这会在一些片段中造成严重问题,我会在他们的onCreate方法中启动一些后台进程......

请帮帮我......我真的不知道该怎么做.非常感谢您的任何建议或想法!

Bhi*_*fer 24

好吧,我找到了解决方案.我不得不将片段管理器的代码从onStart移动到onCreate并检查nullsavedInstanceState.好吧,我不知道它是savedInstanceState自动保存和恢复的.很高兴知道!

编辑:并且要完全正确,即当savedInstanceState不为null时恢复片段,应该有:

    if(savedInstanceState == null)
    {
        mFragment = onCreatePane();     
        mFragment.setArguments(Utils.intentToFragmentArguments(getIntent()));

        getSupportFragmentManager() 
        .beginTransaction()
        .add(R.id.root_container,mFragment)
        .commit();
    } 
    else
    {
        mFragment = getSupportFragmentManager().findFragmentById(R.id.root_container);
    }
Run Code Online (Sandbox Code Playgroud)