回答
在带有UI的Fragment
中,您经常会将一些View
作为实例状态来加速访问。例如指向您的EditText
的链接,因此您不必一直使用findViewById
。
问题是View
保留对Activity
上下文的引用。现在,如果您保留View
,您还保留对该上下文的引用。
如果上下文仍然有效,但典型的保留情况是重新启动活动,那么这没有问题。例如,经常用于屏幕旋转。活动娱乐将创建一个新的上下文,旧的上下文旨在被垃圾收集。但现在不能垃圾收集,因为您的Fragment
仍然有一个旧的参考。
以下示例说明如何不这样做
public class LeakyFragment extends Fragment {
private View mLeak; // retained
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mLeak = inflater.inflate(R.layout.whatever, container, false);
return mLeak;
}
@Override
public void onDestroyView() {
super.onDestroyView();
// not cleaning up.
}
}
为了摆脱这个问题,你需要清除onDestroyView
你的UI的所有引用。一旦Fragment
实例被重新使用,您将被要求在onCreateView
上创建一个新的UI。在onDestroyView
之后保留UI也没有意义。 Ui不会被使用。
在这个例子中的修复才刚刚改变onDestroyView
到
@Override
public void onDestroyView() {
super.onDestroyView();
mLeak = null; // now cleaning up!
}
而除了保持到View
S变量,你显然应该不保持引用到Activity
(例如,从onAttach
- 干净的onDetach
)或任何Context
(除非它是Application
上下文)。
有任何想法,如何处理,这可能会导致空指针山?我有几个动画侦听器,线程,并且每个人都使用其中一个引用,它在onDestroyView中被取消。所以无论何时我使用其中一个引用,我首先必须检查null。这非常不方便。 – Tamas
@Tamas Listeners,Threads,...都可以保持引用,只要它们不保留对任何引用“Activity”的引用即可。如果他们有类似的引用和活动重新使用它不会导致任何有效的,所以你必须更新它无论如何。 – zapl
@Tamas示例:http://pastebin.com/8A18kMym你基本上需要传播'onAttach' /'onDetach'到任何引用上下文和'onCreateView' /'onDestroyView'的任何引用视图的东西。 – zapl
setRetainInstance(true)
用于在Activity重新创建期间保留动态片段的实例,例如屏幕旋转或其他配置更改。这并不意味着系统会永远保留片段。
由于其他原因(例如用户完成活动(即后退))终止Activity时,Fragment应该有资格进行垃圾回收。
保留耦合到Activity的特定对象时要小心。
注意:虽然你可以返回任何对象,你永远不应该传递是联系在一起的活动,如可绘制对象,适配器,一个查看或者某个相关的任何其他对象与上下文。如果这样做,它会泄漏原始活动实例的所有视图和资源。 (泄漏资源意味着您的应用程序会保留它们,并且它们不能被垃圾收集,因此可能会丢失大量内存。)
http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject
您可以在此改变onDestroy()
并调用垃圾收集器。
@Override
public void onDestroy() {
super.onDestroy();
System.gc();
System.gc();
}
有20%的机会可以工作:P 2x'System.gc()'为了安全吗?永远不要依赖'gc()' –
“setRetainInstance”用于在活动重新创建时维护片段的状态。 根据官方文档:如果我们使用“setRetainInstance”,片段生命周期的两个方法将不会被执行(onCreate,onDestroy)。 但是,片段中包含的视图将被重新创建,这是因为生命周期将从“onCreateView”执行。 在这些情况下,如果我们在“onSaveInstanceState”中保存了一些数据,我们应该在“onActivityCreated”中而不是在“onCreate”中请求它。
公报信息:https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
更多信息:https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en
- 1. 内存泄漏,位图,碎片
- 2. iOS中的内存保留和泄漏
- 3. 内存泄漏片段trasaction
- 4. 片段内存泄漏
- 5. Android片段内存泄漏
- 6. 使用loadNibNamed会留下内存泄漏
- 7. 标签/片段和内存泄漏
- 8. 的ctypes和内存泄漏
- 9. Valgrind的和内存泄漏
- 10. 内存泄漏
- 11. 内存泄漏:
- 12. 内存泄漏
- 13. 内存泄漏
- 14. 内存泄漏
- 15. 内存泄漏
- 16. 内存泄漏
- 17. 内存泄漏
- 18. 内存泄漏
- 19. 内存泄漏
- 20. 内存泄漏:
- 21. 内存泄漏
- 22. 内存泄漏
- 23. 内存泄漏
- 24. 内存泄漏
- 25. 内存泄漏
- 26. 内存泄漏
- 27. 内存泄漏
- 28. 大内存页面和碎片
- 29. C和OpenCV内存泄漏
- 30. 内存泄漏NSMutableArray和NSDictionary
只是为了记录的话题,这里有类似的主题:http://stackoverflow.com/q/11182180/693752 – Snicolas
HTTP://计算器。 com/q/11160412/693752 – Snicolas