通用图像加载器有时无法加载图像

我使用的是通用图像加载器,每天都会有大量的图片无法加载。 我正在使用此代码将我的错误分析。

public void onLoadingFailed(String imageUri, View view, FailReason failReason) { try { String fail = failReason.getType().toString(); String fail4 = failReason.getCause().toString(); String sum = fail + " " + fail4; EasyTracker.getTracker().sendException(sum, false); } catch (Exception e) { EasyTracker.getTracker().sendException(e.getMessage(), false); } } 

大多数情况下,它捕获exception,因为getType或getCause为空。 这个问题是在2.1-2.3 Android版本的设备上看到的,但也有一些来自4.0.4甚至4.2.2等新版本的报告。 所以我不能确定是什么导致图像加载失败

另一个问题是IO_ERROR java.io.EOFException ,它主要出现在较新的Android版本上。

第三个最常见的错误是out_of_memory错误…我想加载的图像不大于1mb,但我需要有ScaleType.Exactly,但是当加载较大的图像时,我不caching它们在内存或光盘,以减lessout_of_memory的可能性,但它仍然经常发生。

我的configuration:

 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(xxx.getApplicationContext()) .threadPoolSize(4) .memoryCache(new WeakMemoryCache()) .imageDownloader(new BaseImageDownloader(xxx.getApplicationContext(),10 * 1000, 30 * 1000)) .build(); if(!ImageLoader.getInstance().isInited())      ImageLoader.getInstance().init(config); // options is used for images smaller in size (5kb-150kb) options = new DisplayImageOptions.Builder() .cacheInMemory() .cacheOnDisc() .showStubImage(R.drawable.stub) .showImageOnFail(R.drawable.failed) .imageScaleType(ImageScaleType.EXACTLY) .bitmapConfig(Bitmap.Config.RGB_565) .build(); // options2 is used for images big in size (300kb-1,2mb) options2 = new DisplayImageOptions.Builder() .showStubImage(R.drawable.stub) .showImageOnFail(R.drawable.failed) .imageScaleType(ImageScaleType.NONE) // NONE because I need to have full size bitmap loaded .bitmapConfig(Bitmap.Config.RGB_565) .build(); 

任何人都可以告诉我,我怎么可以优化我的imageLoading以减less失败加载图像? 因为我觉得我失去了一些用户,因为这些不断的失败加载图像。

更新当我改变了代码在onLoadingFailedbuild议nostra,我现在看到,没有.getCause()所有报告是“ .getCause() ”,所有这些都是android 2.2-2.3.6版本报告,没有更新那些。 然而,仍然有很大一部分用户是在较老的机器人,任何想法如何减less这个decode_error? 我在老的机器人上自己检查了应用程序,大部分时间图像都是加载的,但DECODING_ERROR在分析上报告最多。 其次,大多数stream行的原因仍然是IO_ERROR java.io.EOFException

更新2

作为nostrabuild议定制的下载程序,减lessthreadPoolSize到3设置额外的加载 – 如果加载失败尝试再次加载一次放弃之前。 我看到负载下降了大约30%。 但是仍然会发生 – 每天500名活跃用户在3天内发生100次解码错误(仅限2.2-2.3.6版本)和160次EOF错误(4.0次以上)。

更新3

最新的更新版本得到更less的解码错误和EOFExceptions,我想主要是因为我尝试重新加载相同的图像,如果它不能加载第一次。 但是..我现在面临另一个问题:设备上没有空间java.io.IOException: write failed: ENOSPC (No space left on device) 。 我正在使用LimitedDiscCache。

Solutions Collecting From Web of "通用图像加载器有时无法加载图像"

failReason.getType()不能为nullfailReason.getCause()可以。 你应该检查它以防止NPE。

如果您通过ImageLoader.denyNetworkDownloads(true)拒绝networking或发生解码错误, failReason.getCause()可以为null 。 这是因为Android由于某种原因无法解码图像。

顺便说一句,我build议你使用.cacheOnDisc()即使是大的图像( options2 )。 也许尝试其他内存caching实施? 例如LruMemoryCache

我不知道java.io.EOFException的原因,但你可以检测到那个时候使用哪个networking? 移动还是WiFi? 也许尝试使用ImageLoader.handleSlowNetwork(boolean)来切换networkingtypes。

UPD:也尝试减less线程池的大小。 也许这有助于防止解码错误。 UPD2:解码错误可能是由网站redirect到网页造成的。 您可以尝试扩展BaseImageDownloader并在请求中为“User-Agent”头添加空string。

 public class MyImageDownloader extends BaseImageDownloader { private static final int MAX_REDIRECT_COUNT = 5; public MyImageDownloader(Context context) { super(context); } protected InputStream getStreamFromNetwork(String imageUri, Object extra) throws IOException { HttpURLConnection conn = connectTo(imageUri); int redirectCount = 0; while (conn.getResponseCode() / 100 == 3 && redirectCount < MAX_REDIRECT_COUNT) { conn = connectTo(conn.getHeaderField("Location")); redirectCount++; } return new BufferedInputStream(conn.getInputStream(), BUFFER_SIZE); } protected HttpURLConnection connectTo(String url) throws IOException { String encodedUrl = Uri.encode(url, ALLOWED_URI_CHARS); HttpURLConnection conn = (HttpURLConnection) new URL(encodedUrl).openConnection(); conn.setConnectTimeout(connectTimeout); conn.setReadTimeout(readTimeout); conn.setRequestProperty("User-Agent", ""); return conn; } } 

或者从UIL 1.8.5开始:

 public class MyImageDownloader extends BaseImageDownloader { @Override protected HttpURLConnection createConnection(String url) throws IOException { HttpURLConnection conn = super.createConnection(url); conn.setRequestProperty("User-Agent", ""); return conn; } } 

我从来没有使用过Universal Image Loader,但在过去的几周里,有几个非常好的替代品已经发布了,他们可能值得一看。

第一个是Volley,Google在I / O 2013上宣布的新networking库https://developers.google.com/events/io/sessions/325304728

第二个是Square的毕加索。 Square团队在他们的Android库上做了一些非常棒的工作。 http://corner.squareup.com/2013/05/picasso-one-dot-oh.html