2

我正在使用universal-image-loader-1.6.2.jar(最新版本)。我正在尝试使用此库下载和缓存该图像。我有 47 张图片要从服务器下载,总共 5.22 Mb。我的最大图片尺寸为 720X480,大小约为 143kb。它运行良好,直到 40-41 图像之后它给出了错误

11-02 16:30:12.150: E/ImageLoader(31033): null
11-02 16:30:12.150: E/ImageLoader(31033): java.lang.OutOfMemoryError
11-02 16:30:12.150: E/ImageLoader(31033):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-02 16:30:12.150: E/ImageLoader(31033):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
11-02 16:30:12.150: E/ImageLoader(31033):   at com.nostra13.universalimageloader.core.ImageDecoder.decode(ImageDecoder.java:83)
11-02 16:30:12.150: E/ImageLoader(31033):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.saveImageOnDisc(LoadAndDisplayImageTask.java:218)
11-02 16:30:12.150: E/ImageLoader(31033):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:138)
11-02 16:30:12.150: E/ImageLoader(31033):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:72)
11-02 16:30:12.150: E/ImageLoader(31033):   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
11-02 16:30:12.150: E/ImageLoader(31033):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-02 16:30:12.150: E/ImageLoader(31033):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-02 16:30:12.150: E/ImageLoader(31033):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-02 16:30:12.150: E/ImageLoader(31033):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-02 16:30:12.150: E/ImageLoader(31033):   at java.lang.Thread.run(Thread.java:856)
11-02 16:30:47.170: E/Adreno200-ES20(31033): <qgl2DrvAPI_glUseProgram:1318>: **** 31033: glUseProgram(3)
11-02 16:30:47.170: E/Adreno200-ES20(31033): <qgl2DrvAPI_glUseProgram:1318>: **** 31033: glUseProgram(6)

我已经在 git-hub 上看到并实施了关于 OOM 的建议。我跟着他们,我仍然收到错误。这是我的代码

if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
        cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"neongall");
    else
        cacheDir=context.getCacheDir();
    if(!cacheDir.exists())
        cacheDir.mkdirs();

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
    .threadPoolSize(3)
    .threadPriority(Thread.NORM_PRIORITY - 1)
    .memoryCache(new WeakMemoryCache())
    .denyCacheImageMultipleSizesInMemory()
    .offOutOfMemoryHandling()
    .discCacheExtraOptions(720, 480, CompressFormat.JPEG, 75)
    .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
    .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
    .imageDownloader(new URLConnectionImageDownloader(120 * 1000, 120 * 1000)) // connectTimeout (5 s), readTimeout (20 s)
    .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
    .enableLogging()
    .build();
    //Initialize ImageLoader with created configuration. Do it once on Application start.
    imageLoader.init(config);


    options = new DisplayImageOptions.Builder()
    .cacheOnDisc()
    .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
    .displayer(new RoundedBitmapDisplayer(10))
    .build();

提前致谢。

4

1 回答 1

15

首先你的配置:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.threadPoolSize(3) // equal to default value
.threadPriority(Thread.NORM_PRIORITY - 1) // equal to default value
.memoryCache(new WeakMemoryCache())
.denyCacheImageMultipleSizesInMemory()
.offOutOfMemoryHandling()
.discCacheExtraOptions(720, 480, CompressFormat.JPEG, 75)
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // equal to default value
.imageDownloader(new URLConnectionImageDownloader(120 * 1000, 120 * 1000)) // connectTimeout (5 s), readTimeout (20 s)
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // equal to default value
.enableLogging()
.build();

等于

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.memoryCache(new WeakMemoryCache())
.denyCacheImageMultipleSizesInMemory()
.offOutOfMemoryHandling()
.discCacheExtraOptions(720, 480, CompressFormat.JPEG, 75)
.discCache(new UnlimitedDiscCache(cacheDir))
.imageDownloader(new URLConnectionImageDownloader(120 * 1000, 120 * 1000))
.enableLogging()
.build();

不要从自述文件中复制配置!

你为什么关闭 OutOfMemory 处理?如果你这样做,那么你应该自己处理 OOM 错误ImageLoadingListener.onLoadingFailed(FailReason.OUT_OF_MEMORY)

我给你的建议:

  • 删除.offOutOfMemoryHandling()配置中的选项
  • 删除.discCacheExtraOptions(720, 480, CompressFormat.JPEG, 75)配置中的选项
  • .imageScaleType(ImageScaleType.IN_SAMPLE_INT)在显示选项中使用
  • 你真的需要 RoundedBitmapDisplayer 吗?请参阅文档,它会在舍入期间在内存中创建额外的位图。如果可以,请避免使用它。
于 2012-11-03T09:05:35.680 回答