释放未使用View创建新的View

时间:2014-02-17 22:54:25

标签: java android multithreading android-arrayadapter

我的应用程序中有两种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上找到。

1 个答案:

答案 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);

}