2013-05-17 197 views
10

我使用的是通用图像加载程序,并且每天都无法为用户加载大量图像。 我使用此代码将我的错误分析到分析。通用图像加载程序无法加载图像有时

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); 
    } 
} 

大多数情况下,它捕获异常,因为getType或getCause为null。这个问题出现在2.1-2.3 Android版本的设备上,但是有一些来自4.0.4甚至4.2.2等新版本的报告。所以我真的不知道是什么导致图像加载失败

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

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

我的配置:

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获得较少未能加载图像?因为我觉得我失去了一些用户,因为这些不断的失败加载图像。

更新 正如我改变了代码为诺斯特拉上onLoadingFailed建议,我现在看到的,所有不具有.getCause()上的报告是“DECODING_ERROR”,所有这些都是由Android 2.2-2.3.6版本报道,没有新的。然而,我的用户仍然很大一部分是在老的机器人上,任何想法如何减少这个decode_error?我自己在老的机器人上检查了应用程序,并且图像的大部分时间都会加载,但DECODING_ERROR最常报告在分析上。第二对最流行的原因仍然是相同的IO_ERROR java.io.EOFException

更新2

定制下载器为诺斯特拉建议,减少threadPoolSize 3建立额外的负载 - 如果加载失败尝试给前一周时间再次加载向上。我看到装载减少约30%的失败。但仍然会发生 - 500名日常活跃用户在3天内发生100次解码错误(仅限于2.2-2.3.6版本)和160次EOF错误(4.0次及以上)。

更新3

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

回答

5

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

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

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

我不知道java.io.EOFException的原因,但是您可以检测到那个时间使用哪个网络吗?移动还是WiFi?也许尝试使用ImageLoader.handleSlowNetwork(boolean)在网络类型之间切换。

UPD:也尝试减少线程池大小。也许这有助于防止解码错误。 UPD2:解码错误可能是由网站重定向到网页引起的。您可以尝试扩展BaseImageDownloader,并在请求中为“User-Agent”标头添加空字符串。

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; 
    } 
} 
+0

也许我不应该使用casheInMemory,以减少out_of_memory的可能性?我尽最大努力减少服务器端图像的大小(压缩并显示缩略图图像),但我仍然在分析中报告out_of_memory。我自己无法重现任何这些错误。除EOFException外,当我尝试快速扫描已缓存的图像时,它很少发生,并且其中一些无法加载EOFException。对于互联网连接我无法确切地说,但我的大多数用户不在WiFi上,因此他们可能会有缓慢的连接 – Datenshi

+0

也尝试减少线程池大小。也许这有助于防止解码错误。 – NOSTRA

+0

已更新的答案。 UPD2来防止DECODING_ERROR。 – NOSTRA

4

我从来没有使用通用图像装载机但在过去几周内一对夫妇真的很好的替代品已被释放,他们可能是值得一试。

首先是排球,谷歌的新的网络LIB在I/O 2013 https://developers.google.com/events/io/sessions/325304728

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

+0

谢谢,我会看看那些。但问题仍然是关于Universal Image loader :) – Datenshi