目前,我想在配置更改期间保留昂贵的数据结构。我选择不使用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 Fragment(称为UIFragment)将从RetainInstanceFragment
. 每当在 上发生配置更改时,UIFragment
总是UIFragment
会在决定创建新的.RetainInstanceFragment
FragmentManager
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)
知道如何正确删除保留的实例片段吗?