如果我对此有任何错误,请纠正我。这是一种澄清问题,因为我还没有在任何地方看到它明确写过。
在Android 4中,您可以调用setRetainInstance(true)
on a Fragment
这样在配置更改时(这基本上意味着设备旋转),Fragment
java 对象不会被销毁,也不会创建它的新实例。即,实例被保留。
这比 Android 1-3 更理智,也更不令人恼火,因为你不必处理onRetainNonConfiguration
State
罢工>Instance()
并将所有数据捆绑在一起,以便可以将其传递给新的Fragment
(or Activity
) 实例只需再次解绑。这基本上就是您期望发生的情况,并且可以说它应该如何工作Activity
从头开始。
With setRetainInstance(true)
视图也被重新创建(onCreateView()
被调用)如您所期望的轮换。我假设(未测试)资源解析(layout
vs layout-land
) works.
所以我的问题有两个:
- 为什么不是这样的
Activities
从一开始就。
- 为什么这不是默认值?有没有什么理由让你would其实想要你的
Fragment
被无意义地摧毁并轮流重建?因为我想不出任何办法。
Edit
为了澄清我将如何做到这一点:
class MyFragment extends Fragment
{
// All the data.
String mDataToDisplay;
// etc.
// All the views.
TextView mViewToDisplayItIn;
// etc.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
mDataToDisplay = readFromSomeFileOrWhatever(); // Ignoring threading issues for now.
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.my_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
// At this point if mViewToDisplayItIn was not null, the old one will be GC'd.
mViewToDisplayItIn = view.findViewById(R.id.the_text_view);
mViewToDisplayItIn.setText(mDataToDisplay);
}
// Optionally:
@Override
public void onDestroyView()
{
// All the view (and activity) to be GC'd.
mViewToDisplayItIn = null;
}
}
这样配置更改(这基本上意味着设备旋转)
以及更改区域设置、更改 SIM、更改默认字体大小、插入或移除外部键盘、将设备放入扩展坞中或将其从扩展坞中移除等。
您不必处理 onRetainNonConfigurationState()
That's onRetainNonConfigurationInstance()
.
捆绑所有数据,以便将其传递到新的 Fragment(或 Activity)实例,然后再次解绑
您的数据应该已经“捆绑”(例如,私有静态内部类的实例),因此不需要“捆绑”或“解绑”。此外,它通常不应该是“您的所有数据”,除非您喜欢内存泄漏。
我假设(未测试)资源分辨率(布局与布局区域)有效。
Correct.
您是否有任何理由希望您的片段被无意义地销毁并轮流重新创建?
Sure.
正如您所注意到的,所有小部件都被重新创建,因此与小部件绑定的数据成员不仅不需要保留。除非你专门将它们重置为null
以某种方式在保留的片段上,直到onCreateView()
再次调用时,这些数据成员将保留旧的小部件,而旧的小部件将保留旧的活动实例,这将阻止旧的活动实例被垃圾收集。 AFAIK,onCreateView()
在重新显示片段之前不会被调用,这可能不会持续很长一段时间(该片段没有在新方向中使用,或者该片段用于某个页面)ViewPager
用户在旧方向访问过但没有在新方向再次访问,等等)。这意味着保留的片段可能会在相当长的一段时间内保留旧的活动对象。取决于什么else该活动可能已经持续(例如,大型Bitmap
对象),这可能很糟糕。
类似地,本身保存大量数据的片段(在配置更改后可能会或可能不会使用该片段)是不应该保留的片段。
此外,还会有一些片段根本不需要保留任何内容(例如,所有数据都由Loaders
,它们已经意识到配置更改并适当地处理它们)。
等等。
就垃圾收集问题而言,默认不保留片段是最安全的做法。您可以选择保留一些片段,但随后就有责任了you确保你这样做不会把自己搞砸。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)