我正在使用通用图像加载器,我每天都会收到大量无法为用户加载的图像。 我正在使用此代码将错误归结为分析。
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安卓版本的设备上可以看到此问题,但有一些报告来自较新版本,如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
自定义下载器作为nostra建议,将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。
答案 0 :(得分:5)
failReason.getType()
不能null
,failReason.getCause()
可以。你应该检查它以防止NPE。
failReason.getCause()
拒绝网络或发生解码错误,则 null
可以是ImageLoader.denyNetworkDownloads(true)
。这是因为Android无法通过某种原因解码图像。
BTW我建议您使用.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;
}
}
答案 1 :(得分:4)
我从未使用过Universal Image Loader,但在过去的几周内发布了几个非常好的替代品,它们可能值得一看。
第一个是Volley,谷歌在2013年I / O上宣布的新网络库 https://developers.google.com/events/io/sessions/325304728
第二个是Square的毕加索。 Square团队用他们的Android库做了一些非常好的工作。 http://corner.squareup.com/2013/05/picasso-one-dot-oh.html