Android 活动';s onDestroy/Fragment';s onDestroyView集空实践
我正在阅读ListFragment源代码,我看到了以下实现:Android 活动';s onDestroy/Fragment';s onDestroyView集空实践,android,android-activity,android-fragments,ondestroy,Android,Android Activity,Android Fragments,Ondestroy,我正在阅读ListFragment源代码,我看到了以下实现: ListAdapter mAdapter; ListView mList; View mEmptyView; TextView mStandardEmptyView; View mProgressContainer; View mListContainer; CharSequence mEmptyText; boolean mListShown; /** * Detach from list view. */ @Override
ListAdapter mAdapter;
ListView mList;
View mEmptyView;
TextView mStandardEmptyView;
View mProgressContainer;
View mListContainer;
CharSequence mEmptyText;
boolean mListShown;
/**
* Detach from list view.
*/
@Override
public void onDestroyView() {
mHandler.removeCallbacks(mRequestFocus);
mList = null;
mListShown = false;
mEmptyView = mProgressContainer = mListContainer = null;
mStandardEmptyView = null;
super.onDestroyView();
}
在这个函数中,Google开发者将ListFragment中声明的所有视图字段设置为Null,并删除回调“mRequestFocus”
在列表活动中源代码。谷歌开发者实现如下:
protected ListAdapter mAdapter;
protected ListView mList;
private Handler mHandler = new Handler();
@Override
protected void onDestroy() {
mHandler.removeCallbacks(mRequestFocus);
super.onDestroy();
}
我没有看到谷歌开发人员在ListActivity的onDestroy中将Null设置为mList,就像他们在ListFragment类中所做的那样。
我的问题是
谢谢你的想法 如果不影响应用程序的逻辑,则无需设置null。例如,如果(mList==null).那么片段和活动之间不同的原因是因为它们的生命周期不同。当
活动
被销毁时,它将永远消失。但是,片段在实际销毁之前可能会多次创建和销毁其视图。为了澄清,在活动中:
onDestroy()
onCreate()
对于同一活动实例,不会按顺序发生。对于片段,以下内容完全有效:
onCreate()
onCreateView()
onDestroyView()
onCreateView()
onDestroyView()
onDestroy()
您可以看到的一种情况是,片段进入后堆栈。它的视图将被销毁(因为它不再可见),但当用户按back键返回实例时,实例将保留在周围,以便轻松恢复(此时将再次调用onCreateView()
)
在onDestroyView()
之后,您可以(很可能应该)释放所有视图
引用,以允许对它们进行垃圾收集。在许多情况下,这是不必要的,就像它只是在配置更改期间发生一样,onDestroy()
将立即跟进,整个实例将被垃圾收集
本质上,我想说,在onDestroyView()
中释放任何和所有视图引用是一种好的做法,如果你的应用程序有一个大的后台,它可以节省相当多的内存。由于API 19,没有必要在onDestroy()
和onDestroyView()
中注销你的侦听器,这是onStop()中挂起的
并且没有必要将视图设置为null。使用Jetpack上的按钮
因此,在大多数情况下,不需要在片段中实现onDestroyView()
。有关更多信息,请查看关于的博客文章。这只需要137秒。如果我不设置Null,内存泄漏如何?这是不可能的,因为fragment对象下的所有引用,这意味着一旦fragment对象退出,所有视图和其他视图也退出。@VladimirLichonos事实上,这是非常可能的,特别是当一个片段上设置了setRetainInstance(true)
时。如果保留这些视图引用,则很容易泄漏活动实例(因为视图保留对活动的引用)。使用视图和setRetainInstance时,这是一个奇怪的用例。但同样,它是基于我上面提到的片段逻辑的。非常好的解释。我有个问题。为什么谷歌开发者没有在ListFragment的onDestroyView中将Null设置为mAdapter。将Null设置为非ui字段(如mAdapter)是不必要的?这是一个好问题。通常情况下,这并不重要,但适配器往往也包含对活动上下文的引用。我认为它遵守了方法的约定,即onDestroyVIEW
,因此它们只销毁视图引用。我认为,如果您调用setListAdapter()
,然后稍后调用getListAdapter()
,这将是一种意外的行为,并且它会莫名其妙地null
。由于适配器不是一个昂贵的对象(setRetainInstance()可能泄漏活动的情况除外),因此释放它并没有多大好处。我想知道在绑定之前在oncreateview中解除绑定是否是更好的方法?当您绑定到oncreateview
中的(子)视图的新实例时,这将解除(子)视图的旧实例的绑定。在分配新值之前设置null
是不必要的。