我在ListView上遇到内存泄漏。我非常清楚,Android中列表的优化是一个非常常见的主题,互联网上有很多教程,堆栈中的问题都有关于它的问题,但似乎没有解决我的问题。
问题是当单击Back键时,行的视图所消耗的内存不会被“释放”
我已经将我的getView实现缩短了,所以我不填充信息,只是给行布局充气:
@Override
public View getView(int position, View v, ViewGroup parent) {
if(v == null){
LayoutInflater vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.listview_row, null);
}
return v;
}
适配器的构造函数也非常简单,所以我没有在全局变量上保存任何内容,也没有填充行的信息(在p_items中):
public IconListView(Context p_context, int p_textViewResourceId, ArrayList<IconListViewRow> p_items,) {
super(p_context, p_textViewResourceId, p_items);
}
行的布局非常复杂,它包含一些嵌套在线性和相对布局中的文本视图,因此需要大量内存(假设每行500 Kb)。但是,如果我将复杂性降低到只有一些带有文本视图的线性布局,那么消耗的内存量会大大减少,但是当我单击“返回”按钮时,它永远不会“释放”,因此应用程序占用的内存增长到无穷大。
我读过的任何教程似乎都会解决这个问题。列表的性能有一些聪明的改进,比如ViewHolder,但没有与此相关。实际上,它们使用非常简单的行布局,因此您无法理解令人惊讶的内存消耗,尽管如此,它总是会增长到无穷大。
答案 0 :(得分:0)
我认为你已经正确地做了一切,然后我建议你进行记忆分析。我确信这是一个你引用视图或它的视图组的情况,这会阻止你的列表被垃圾收集。
答案 1 :(得分:0)
当按下后退按钮时,您的活动及其内容仍处于活动状态且未被处理。如果你想在这种情况下释放内存,你必须在onPause()方法中做出反应。作为第一个meassure,我会尝试从列表适配器返回0并通知已更改数据的列表。 如果它没有帮助 - 那么你可能必须完全处理清单。
但是你必须要知道,如果用户再次呼叫活动,你会购买更长启动时间的内存
答案 2 :(得分:0)
我发现了一些相关的东西。当您为行的布局使用自定义组件时,例如:
MyTextView extends TextView
MyButton extends Button
内存泄露。由于我在ListViews上放弃了这些组件,因此我的应用程序占用的内存减少了很多。
至少,我的自定义组件会发生这种情况。我不能假设每个自定义组件都会发生这种情况,也许我的错误,但要小心。