目前,我希望在配置更改期间保留昂贵的数据结构.我选择不使用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)
知道如何正确删除保留的实例片段吗?