2012-02-28 55 views
3

我正在写一个游戏,到目前为止需要使用大约200个PNG总共〜14 MB,所有尺寸范围从250x150到600x400(这些都是xhdpi drawables,现在我让Android做低dpi的调整大小)。Android游戏资源加载内存不足

问题是,如果我在游戏启动时全部加载它们,则在模拟器(1 GB RAM)和Galaxy S设备(512 MB RAM)上约20秒后出现内存不足错误)。

我见过有更多资源的游戏,甚至有数百MB的游戏。如何在不超过内存限制的情况下快速加载资源? 14 MB不应该那么多。

现在我正在使用BitmapFactory.decodeResource()在游戏开始之前加载几个for循环内的每个位图。我也尝试使用BitmapFactory.OptionsinSampleSize设置为4,这可以解决内存不足的问题,但不是缓慢加载,仍然需要大约20秒。我宁愿不必这样做,因为如果我将图像缩小4倍,则根本无法考虑hdpi和xhdpi屏幕 - 质量会更差。我也尝试使用getDrawable(),但它没有区别。

我也认为在需要的时候(比赛开始后)加载每个资源,但:

  1. 这是不是可以慢? - 现在系统在每个负载之间分配更多的内存,这需要100-300 ms。这会严重减慢我的帧速率。
  2. 如果我缓存每个图像,所以它只加载一次,最终我将需要在同一级别的所有人,所以这不应该解决内存不足的错误。

我知道一个位图占用的内存空间比磁盘上的PNG更多 - 分配大约40 MB时出现错误。没有办法只是加载内存中的14 MB,并根据需要从它们中构建位图,或者放弃一些速度的东西(这是一个非常基本的2D游戏,所以我并不需要很多处理功率或最大fps)以换取更多的空闲内存?

此外,我有很多小约10-16帧的动画。每一个都是一个单独的文件。将它们合并到单个文件并加载它们会有什么好处吗?我看不出它有助于内存使用情况,但可以帮助加载时间?

更新:我改变了我的代码加载每一帧,显示它,然后回收()它。这导致我可以告诉是5 FPS,所以我不认为我可以这样做

+0

你确定你需要在游戏的每一个时刻所有这些图片吗? – Egor 2012-02-28 10:44:14

+0

@Egor - 它们不会同时在屏幕上显示,因为它们大部分都是大约10个不同对象的帧,可以同时显示在屏幕上。但是在2-3秒的时间间隔内,如果不是全部都会显示,那么这个机会绝大部分都是可能的。 – IVlad 2012-02-28 10:49:19

+0

主要的问题是,在许多设备(和模拟器,我相信),堆大小只有16 MB。当使用BitmapFactory将14 MB图像加载到内存中时,每个图像都被解码为一个位图,因此远远超过了分配的16 MB内存。如果你真的需要有这么大的图像,你需要找到一种方法来随时随地加载/释放它们。否则,你将不得不使用更小的位图。另外,请记住,加载较小尺寸的图像要比加载较大图像要快得多,并且让Android缩小图像的速度要快得多。 – 2012-02-28 11:02:18

回答

0

尝试扩展您的选项(2)与SoftReference缓存的位图。这样,你只会加载你的位图一次,但如果虚拟机内存不足,这将是第一个被释放的候选人。就像这样:

public class MemoryCache { 
    private HashMap<String, SoftReference<Bitmap>> cache=new HashMap<String, SoftReference<Bitmap>>(); 

    public Bitmap get(String id){ 
     if(!cache.containsKey(id)) 
      return null; 
     SoftReference<Bitmap> ref=cache.get(id); 
     return ref.get(); 
    } 

    public void put(String id, Bitmap bitmap){ 
     cache.put(id, new SoftReference<Bitmap>(bitmap)); 
    } 

    public void clear() { 
     cache.clear(); 
    } 
}