我正在为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
}
}
因此将它们添加回可用数组中,以便在需要时可以在上述方法中重复使用它们。
尽管如此,我仍然在我的应用程序中遇到大量延迟。可能是因为我从数组中删除了对象吗?
我做错了什么?
谢谢!
答案 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个对象使用它。
最后,正如我之前在评论中所说,你会希望尽可能减少所有精灵表的大小。