【问题标题】:Optimizing GridLayout's memory usage优化 GridLayout 的内存使用
【发布时间】:2014-10-02 13:15:26
【问题描述】:

我正在使用 android-support-v7-gridlayout 在 Android 中模拟基于图块的地图。

我在调试期间顺利快速地实现它,直到我在巨大的数据规模上对其进行测试。实际数据约为 ~700x400 (row-column),我刚刚在 400x100 中对其进行了测试,但应用程序刚刚崩溃并抛出OutOfMemoryException。然后我减少了数据,直到它实际运行在 300x100 上。它没有滞后或者我没有任何 CPU 性能问题,唯一的问题是 inadequate memory。

这就是我在网格布局中添加ImageViews 的方式:

public boolean genMap(GridLayout gl) {

    gl.removeAllViews();
    gl.setRowCount( mapFile.getRowCount() );
    gl.setColumnCount( mapFile.getColCount() );

    try {

    for (int row = 0; row < mapFile.getRowCount(); ++row) {
        for (int col = 0; col < mapFile.getColCount(); ++col) {

            com.gridlayout.GridLayout.Spec rowspan = GridLayout.spec(row, 1); 
            com.gridlayout.GridLayout.Spec colspan = GridLayout.spec(col, 1);
            GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowspan, colspan);
            lp.width = Cell.SIZE;
            lp.height = Cell.SIZE;

            Cell cell = genNewCell( ctx.getApplicationContext(), row, col );

            gl.addView( cell, lp );
        }
    }

        return true;

    } catch (Exception e) {
        return false;
    }

}

Cell 是 ImageView 的子类

也许,我也想到了将加载唯一可见视图的延迟加载模式,但我想知道GridLayout 是否已经实现了它。

更新 1

GridView 似乎不是我想要的。它不能对角滚动,而且不能同时具有水平和垂直滚动条。我想要实现的是类似于 GoogleMaps 的 ViewGroup 布局,您可以在其中以二维方式滚动,并且每个 cells 内存分配/释放都是自动管理的。我认为GridLayout 是我最后的希望,因为我看不到任何 ViewGroup w/c 实现了我想要的。

所以我的问题是,我怎样才能回收那些在屏幕上尚不可见的单元格,同时保持布局不变?

【问题讨论】:

  • 屏幕上一次可以看到多少个“单元格”?如果它们很少,那么您可能应该实现一个自定义适配器,它只加载任何给定时间所需的图像。
  • @Code-Apprentice 取决于缩放系数。也许大约 16x8。啊,我虽然它只适用于listview?
  • @Code-Apprentice 有没有办法假装我在 GridLayout 中添加了一些孩子只是为了正确对齐网格内的单元格。因为大部分单元格没有使用?
  • 你需要更改你的标题,因为它说你正在使用GridView。

标签: android memory-management out-of-memory android-gridlayout


【解决方案1】:

GridLayout 不做任何动态内存管理,只是简单地创建一切,不管它是否真的在屏幕上。您需要使用类似 GridView 的东西。使用 GridView,理论上可以支持无限数量的项目。现在因为你想做水平滚动,你需要一个自定义的 GridView 实现。类似https://github.com/jess-anders/two-way-gridview。

如果您没有从我的帖子中删除任何内容,请不要在网格布局中执行此操作。你可以测试一整天,但每部手机都不同,有些手机的内存或多或少。

编辑 1:

随着 android L 中新 RecyclerView 的发布,这也可能更容易,但我还没有深入研究。

【讨论】:

  • 但它不允许我把这个 app:scrollDirectionPortrait="vertical|horizontal" 和 app:scrollDirectionLandscape="horizontal|vertical" 。我已经对其进行了测试,但我一次只有一个工作滚动条。
  • 嗯,这在水平方向上有多大?你可以只吃掉屏幕上多余的列,然后用像stackoverflow.com/questions/16299633/… 这样的水平滚动条包裹一个网格视图。您必须能够指定我认为的宽度。否则,它将是无限的。我很困惑这个控件似乎不存在(在库中)。
  • 即使我设置了two-way-gridview 的colCount,它也不允许扩展超出屏幕边界,而是压缩每个单元格直到适合为止。每个单元格大小约为 32x32
  • 我想要实现的是类似于GoogleMap 的ViewGroup 布局。
  • 我是说你会有一个水平滚动,你想要 itemSize * numberOfItemsDesired 的大小。这样它就不会把它们都聚集在屏幕上。但是,我不想这么说,但是 OWADVL 使用 webview 的想法实际上可能更容易。您应该能够在高度修改的网格视图中完成此操作,但坦率地说,这将是很多工作。不过,如果你这样做了,你可以为下一个人开源它。
【解决方案2】:

在我看来,您应该为此使用 Webview。已经解决了滚动、缩放、内存问题。

【讨论】:

  • 你有任何链接解释它是如何管理每个Views的吗?
猜你喜欢
  • 2016-09-01
  • 2014-05-05
  • 2011-03-09
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 2015-10-02
相关资源
最近更新 更多