2010-06-30 40 views
1

我必须在按钮中显示大约100个图标(每个50x50)。我正在下载包含所有100个图标的大png图像,然后使用Image.subImage()方法创建每个图标。大图像与许多图标或一个图像一个图标?

但我的应用程序得到OutOfMemoryError

我想这大约2溶液:

  1. 下载100个图标焦油(合并成单一的)文件。所以我可以 一个一个地创建图标。大图像不需要在内存中,直到我 创建最后一个图标。
  2. 下载大图像但不创建小图标。然后覆盖按钮 类从大图像绘制图像(图标)。

哪一个是最好的解决方案?或者你有任何其他解决方案来解决这个问题。

回答

2

LWUIT专为小型设备而设计,所以您应该设计自己的代码。所以一个大的图像不是一个好主意。

你应该真的使用单独的图像。只保留那些你可以看到的记忆。或者你将继续陷入内存错误。

我会这样处理它。 获取缓存图。 如果你想要一张图片,请检查它是否已经存在于cachemap中。 如果是,则使用cachemap中的图像 如果它没有下载它并将图像放入cachemap中。 当内存不足时,从cachemap中删除最后一张图像并下载新图像。

if (imageCache.get(url) != null) { 
     //#debug 
     System.out.println("Get cached image from: " + url); 

     asyncImage.setImage((Image) imageCache.get(url)); 
     asyncImage.setQueued(false); 
    } else { 
     //#debug 
     System.out.println("Start download image from:" + url); 

     map.put(url, asyncImage); 

     ImageDownloadService d = new ImageDownloadService(url, new ActionListener() { 

      public void actionPerformed(ActionEvent evt) { 

       NetworkEvent n = (NetworkEvent) evt; 
       Image image = (Image) n.getMetaData(); 
       String url = n.getConnectionRequest().getUrl(); 
       AsyncImage asyncImage = (AsyncImage) ImageManager.this.map.get(url); 
       map.put(url, asyncImage); 
       asyncImage.setImage(image); 
       map.remove(url); 
       imageCache.put(url, asyncImage.getImage()); 
       asyncImage.setQueued(false); 
       if (Display.getInstance().getCurrent() instanceof AsyncLoadable) { 
        ((AsyncLoadable) Display.getInstance().getCurrent()).asyncLoaded(); 
       } else { 
        Display.getInstance().getCurrent().repaint(); 
       } 
       //#debug 
       System.out.println("Retrieved image from:" + url); 
      } 
     }); 
     d.addResponseCodeListener(new ActionListener() { 

      public void actionPerformed(ActionEvent evt) { 
       NetworkEvent n = (NetworkEvent) evt; 
       String url = n.getConnectionRequest().getUrl(); 
       AsyncImage asyncImage = (AsyncImage) ImageManager.this.map.get(url); 
       asyncImage.setQueued(false); 
       map.remove(n.getConnectionRequest().getUrl()); 
       //#debug 
       System.out.println("Failed image from:" + url); 
      } 
     }); 

     NetworkManager.getInstance().addToQueue(d); 
+1

答案是正确的,所以我投了票。但是,您不需要任何奇特的缓存映射。我们在LWUIT中有EncodedImage类(默认情况下用于从资源加载的图像),并将编码的图像存储在其中。这意味着默认情况下它将占用更少的内存。如果您将它与不保存RAM中的数据的列表结合使用,您将有效地允许GC即时收集所有位图图像数据。 – 2011-11-24 10:15:16

相关问题