我的应用程序中有两种ArrayAdapter可以加载(或多或少)动态数据。 第一个绑定到一个线程,该线程每秒触发一次以刷新数据。 第二个用onClick动作刷新数据。
现在当我运行我的应用程序时,我可以使用dumpsys meminfo查看View计数器 不断增加(在线程片段上)。 显然,这会在几秒钟/几分钟后导致巨大的内存泄漏。相同 确实发生在onClick上。
我的假设是那些“旧”数据仍然存储在那些视图中,而不是 得到释放。有没有办法删除每个旧视图? 我的适配器位于此处; https://github.com/Blechd0se/android_packages_apps_AeroControl/blob/master/AeroControl/src/com/aero/control/adapter/AeroAdapter.java
使用适配器的主要方法是(createList()); https://github.com/Blechd0se/android_packages_apps_AeroControl/blob/master/AeroControl/src/com/aero/control/fragments/AeroFragment.java
还是有另一种方法可以释放那些不需要的视图吗?
修改
如果有人感兴趣,我找到了解决方案;
如上所述,每当我更改数据时,我都需要使用notifyDataSetChanged() - Method。
只有使用List时才可以这样做。在我的例子中,它是List<adapterInit>
我使用上面提到的方法以及clear()
。每秒也设置addAdmpter
是一个非常糟糕的主意。现在我只更改数据,结果如预期。查看计数
从~15000下降到100-200。
补丁可以在我的github上找到。
答案 0 :(得分:0)
通过创建新适配器(而不是告诉适配器数据已更改),您(通过下面的代码)会刷新数据。尝试将数据传递给适配器,然后调用notifyDataSetChanged();
这样可以防止您每秒发送十几个新视图。
其次,您可能希望查看垃圾收集器是否在某些时候清理它们。由于您每秒创建多个视图,因此您可能比gc可以合理地保持更快地创建视图。如果程序达到临界点(不确定),它可能会暂停您的程序。看看你是否会因为内存不足而崩溃,看看它是否真的是内存泄漏。
private RefreshThread mRefreshThread = new RefreshThread();
private Handler mRefreshHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what >= 1) {
if (isVisible() && mVisible) {
createList();
mVisible = true;
} else {
// Do nothing
}
}
}
};
public void createList() {
// Default Overview Menu
adapterInit overview_data[] = new adapterInit[]
{
// First Value (0) is for loadable images.
new adapterInit(getString(R.string.kernel_version), AeroActivity.shell.getKernel()),
new adapterInit(getString(R.string.current_governor), AeroActivity.shell.getInfo(GOV_FILE)),
new adapterInit(getString(R.string.current_io_governor), AeroActivity.shell.getInfo(GOV_IO_FILE)),
new adapterInit(getString(R.string.current_cpu_speed), getFreqPerCore()),
new adapterInit(getString(R.string.current_gpu_speed), AeroActivity.shell.toMHz((AeroActivity.shell.getInfo(gpu_file).substring(0, AeroActivity.shell.getInfo(gpu_file).length() - 3)))),
new adapterInit(getString(R.string.available_memory), AeroActivity.shell.getMemory(FILENAME_PROC_MEMINFO))
};
listView1 = (ListView) root.findViewById(R.id.listView1);
adapter = new AeroAdapter(getActivity(),
R.layout.overviewlist_item, overview_data);
listView1.setAdapter(adapter);
}