Dat*_*shi 10 android universal-image-loader
我正在使用通用图像加载器,我每天都会收到大量无法为用户加载的图像.我正在使用此代码将错误归结为分析.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
大部分时间它捕获异常,因为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();
Run Code Online (Sandbox Code Playgroud)
谁能告诉我如何优化我的imageLoading以减少加载图像的失败?因为我觉得我失去了一些用户因为这些不断加载图像的失败.
更新
当我更改了nostra建议的代码时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.
failReason.getType()不能null但failReason.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;
}
}
Run Code Online (Sandbox Code Playgroud)
或者自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;
}
}
Run Code Online (Sandbox Code Playgroud)