Android游戏垃圾收集滞后替代品?

时间:2014-03-03 00:47:28

标签: java android arrays arraylist bitmap

我正在为Android创建游戏。我注意到,每当垃圾收集器启动时,游戏就会遇到大量延迟。

首次运行App时,将创建所有对象并将其添加到arrayLists中,如下所示:

br1 = ImgLoader.getResizedBitmap(BitmapFactory.decodeResource(
            context.getResources(), R.drawable.branchfl, MainActivity.opt),
            MainActivity.height / 12, MainActivity.width / 6);

for (int i = 0; i < 10; ++i) {
        branches_available.add(new Sprite("Branch", br1, 0, 0));
    }

Sprite对象由一个Bitmap和几个允许我修改所述Bitmap的方法组成。 所以在上面的代码中,我将10个Sprite存储到ArrayList中。现在稍后在代码中,我需要动态地将所述精灵生成到我的关卡中。所以我所做的就是:

if (rand == 1) {
            branches_available.get(0).image = bToAdd;
            branches_available.get(0).xPos = (screenWidth - treeWid - bToAdd
                    .getWidth()) + bToAdd.getWidth() / 18;
            branches_available.get(0).yPos = 0 - bToAdd.getHeight();
            branches_available.get(0).height = bToAdd.getHeight();
            branches_available.get(0).width = bToAdd.getWidth();
            branches.add(branches_available.get(0));
            branches_available.remove(0);

这将从第一个数组中获取对象并将其添加到第二个数组中。并且在draw方法中,仅绘制第二个arrayList。现在,当对象离开屏幕时,我会执行以下操作:

branchesSize = branches.size();
    for (int i = 0; i < branchesSize; ++i) {
        branches.get(i).move(0, speed);

        if (branches.get(i).yPos > screenHeight) {
            branches_available.add(branches.get(i));
            branches.remove(i);
            i--;
            branchesSize -= 1;
            // System.gc(); // Force Garbage Collection
        }
    }

因此将它们添加回可用数组中,以便在需要时可以在上述方法中重复使用它们。

尽管如此,我仍然在我的应用程序中遇到大量延迟。可能是因为我从数组中删除了对象吗?

我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

尝试使用HashMap<String,Bitmap>并初始化它,以便为您需要的每个图像都有一个键,并将该键设为图像名称。然后创建一个函数,您可以使用该键询问图像,该函数将在地图中查找它。如果键上的位图为null,则加载位图并将其设置为键。需要时,您可以使用迭代器迭代hashmap。每次加载位图时,通过将新位图的大小添加到成员字段来跟踪地图中所有位图的大小。当所有位图的总大小开始接近您设置的阈值时,找出一种选择此时不再需要的位图的方法,并调用bitmap.recycle,将该键的值设置为null,减去大小从所有位图的总大小中删除的位图,并通知垃圾收集器。

这将解决阵列列表的一些性能问题,并有助于尽快清理内存。棘手的事情是决定要发布什么位图,如果你想要,在需要之前预测或知道:哪些位图进入内存。

绘制精灵时,最简单的方法是知道偏移量和当前精灵。例如,如果你有一个500x200精灵,第一行有5帧,第二行有5帧(所以5列2行),你知道精灵从左到右的进展,所以从( 0,0)到(5,0)然后向下1和从左到右再次(1,0)到(1,5)然后再回到开始于(0,0),然后你可以创建一个简单的函数会给你你需要的东西。

在OpenGL和Canvas中,我能够使用偏移来计算整个位图的哪个部分根据当前帧进行绘制,这样我在任何时候都不会在内存中有多于1个位图副本,即使屏幕上有100个对象使用它。

最后,正如我之前在评论中所说,你会希望尽可能减少所有精灵表的大小。