微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

android – 如何正确删除保留的实例片段

目前,我希望在配置更改期间保留昂贵的数据结构.我选择不使用Bundle来处理它,因为昂贵的数据结构是不可分割的.

因此,我使用非UI片段(称为RetainInstanceFragment),其setRetainInstance(true)来保存数据结构.

public class RetainInstanceFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Creating expensive data structure
        expensiveDataStructure = CreateExpensiveDataStructure();

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

    public ExpensiveDataStructure expensiveDataStructure = null;
}

UI片段(称为UIFragment)将从RetainInstanceFragment获取昂贵的数据结构.每当UIFragment上有配置更改时,UIFragment将始终尝试从FragmentManager获取“缓存”RetainInstanceFragment,然后才决定创建新的RetainInstanceFragment.

示例代码如下.

public class UIFragment extends SherlockListFragment
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        FragmentManager fm = getFragmentManager();

        // Check to see if we have retained the worker fragment.
        retainInstanceFragment = (RetainInstanceFragment)fm.findFragmentByTag("data");

        // If not retained (or first time running),we need to create it.
        if (retainInstanceFragment == null) {
            retainInstanceFragment = new RetainInstanceFragment();
            fm.beginTransaction().add(watchlistArrayFragment,"data").commit();
        } else {
            // We can re-use retainInstanceFragment.expensiveDataStructure even
            // after configuration change.
        }
    }
}

但是,有一个问题.每当我摧毁旧的UIFragment并用新的UIFragment替换它时,我都希望旧的RetainInstanceFragment也会被销毁.以下是我如何销毁和创建新的UIFragment

public class MyFragmentActivity extends SlidingFragmentActivity    
    // Being triggered when there is different menu item in sliding menu being
    // selected.
    public void selectActiveContent(Country country) {
        Fragment fragment = new UIFragment(country);
        getSupportFragmentManager().beginTransaction().replace(R.id.content,fragment).commitAllowingStateLoss();
    }

但旧的RetainInstanceFragment永远不会被破坏.

我的猜测是,也许我忘了在UIFragment中进行清理.因此,我添加以下代码

UIFragment

@Override
public void onDetach() {
    super.onDetach();
    // To differentiate whether this is a configuration changes,or we are
    // removing away this fragment?
    if (this.isRemoving()) {
        FragmentManager fm = getFragmentManager();
        fm.beginTransaction().remove(retainInstanceFragment).commit();
    }
}

但是,它并不是一直有效.我执行了几次滑动菜单点击.

1. selectActiveContent() -> Create new UIFragment and new RetainInstanceFragment
2. selectActiveContent() -> Create new UIFragment,but re-use prevIoUs RetainInstanceFragment. (Wrong behavior)
3. selectActiveContent() -> Create new UIFragment,and new RetainInstanceFragment.
4. selectActiveContent() -> Create new UIFragment,but re-use prevIoUs RetainInstanceFragment. (Wrong behavior)

知道如何正确删除保留的实例片段吗?

解决方法

正如@Luksprog所建议的,以下方法有效.但是,它仍然无法解释为什么通过onDetach完成的先前清理不起作用.如果有人能解释为什么这个解决方案有效,而以前没有,我会非常感激.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐