从URL加载大图像时出现OutOfMemory错误

时间:2013-04-04 13:12:46

标签: android lazy-loading

我正在使用从这个link延迟加载来设置来自url的图像,并且我有非常大的位图..在我的listview中有很多图像要加载,当我滚动listview 20-30次时它会出错outofmemory ..怎么样,我能解决这个错误..?

4 个答案:

答案 0 :(得分:1)

您需要确保在可能的情况下进行下采样,并且由于您使用的是ListView,因此您还可以通过在内存或磁盘上缓存图像来获益。

请阅读此处的最佳做法:Displaying Bitmaps Effeciently

如果您正在寻找一种更简单的方法来实施最佳实践,请考虑使用帮助程序库来加载图像。这是一个很好的:Android-Universal-ImageLoader

答案 1 :(得分:1)

Outof MemoryError

在使用可用平台资源无法满足内存请求时抛出此异常。这样的请求可以由正在运行的应用程序或VM的内部功能进行。

因此您的图像太大而且超出了VM分配的内存。缩小图像或使用以下库。

您可以使用

  1. 懒惰列表

  2. Universal Image Loader

  3. Lazy List是使用url从sdcard或fomr服务器延迟加载图像。这就像点播加载图片一样。

    图像可以缓存到本地SD卡或手机存储卡中。网址被认为是关键。如果密钥存在于sdcard显示图像来自SD卡,则通过从服务器下载显示图像并将其缓存到您选择的位置。可以设置缓存限制。您还可以选择自己的位置来缓存图像。缓存也可以被清除。

    而不是用户等待下载大图像,然后显示延迟列表按需加载图像。由于缓存了图像区域,您可以离线显示图像。

    https://github.com/thest1/LazyList。懒惰列表

    在你的getview中

     imageLoader.DisplayImage(imageurl, imageview);
    

    ImageLoader显示方法

    public void DisplayImage(String url, ImageView imageView) //url and imageview as parameters
    {
    imageViews.put(imageView, url);
    Bitmap bitmap=memoryCache.get(url);   //get image from cache using url as key
    if(bitmap!=null)         //if image exists
        imageView.setImageBitmap(bitmap);  //dispaly iamge
     else   //downlaod image and dispaly. add to cache.
     {
        queuePhoto(url, imageView);
        imageView.setImageResource(stub_id);
     }
    

    } Lazy List的替代方案是Universal Image Loader

    https://github.com/nostra13/Android-Universal-Image-Loader。它基于Lazy List(基于相同的原理)。但它有很多其他配置。我更喜欢使用通用图像加载器因为它为您提供了更多配置选项。如果下载失败,您可以显示错误图像。可以显示带圆角的图像。可以缓存在光盘或内存上。可压缩图像。

    在自定义适配器构造函数

      File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");
    
      // Get singletone instance of ImageLoader
      imageLoader = ImageLoader.getInstance();
      // Create configuration for ImageLoader (all options are optional)
      ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
          // You can pass your own memory cache implementation
         .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
         .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
         .enableLogging()
         .build();
       // Initialize ImageLoader with created configuration. Do it once.
       imageLoader.init(config);
       options = new DisplayImageOptions.Builder()
       .showStubImage(R.drawable.stub_id)//display stub image
       .cacheInMemory()
       .cacheOnDisc()
       .displayer(new RoundedBitmapDisplayer(20))
       .build();
    

    在你的getView()

       ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
       imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options
    

    您可以配置其他选项以满足您的需求。

    这是作者所说的。(直接来自主题实用信息下的链接)

    如果您使用通用图片加载器经常在您的应用中获得OutOfMemoryError ,请尝试下一步(所有这些或几个):

    1. 减少配置中的线程池大小(.threadPoolSize(...))。建议使用1 - 5。 在显示选项中使用.bitmapConfig(Bitmap.Config.RGB_565)。 RGB_565中的位图消耗的内存比ARGB_8888少2倍。

    2. 在配置中使用.memoryCache(new WeakMemoryCache())或在显示选项中禁用内存中的缓存(不要调用.cacheInMemory())。

    3. 在显示选项中使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)。或者尝试.imageScaleType(ImageScaleType.EXACTLY)。

    4. 避免使用RoundedBitmapDisplayer。它使用ARGB_8888配置创建新的Bitmap对象,以便在工作期间显示。

    5. 除了延迟加载/通用图像加载器,您还可以使用视图支架进行平滑滚动和性能。

      http://developer.android.com/training/improving-layouts/smooth-scrolling.html

答案 2 :(得分:0)

发生此错误,因为图像很大。您可以通过下面提到的方法有效地处理它。

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

答案 3 :(得分:0)

检查此库是否延迟加载Android-Universal-Image-Loader。 该库为异步图像加载,缓存和显示提供了可重用的工具。它最初基于延迟加载项目,并且从那时起经过了大量的重构和改进。

相关问题