在做Android 中列表图片异步是遇到一个奇怪的问题,加载网网络图片有很大的几率出现加载失败。
没有任何错误信息,只有一个--- decoder->decode returned false的输出。
加载图片的代码如下:
protected Drawable loadImageFromUrl(String imageUrl) { LogUtils.d(this.getClass(), "start loadImage:("+imageUrl+") "); InputStream is = null; Drawable drawable = null; HttpURLConnection conn = null; String contentType = null; try { URL url = new URL(imageUrl); conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true); //default conn.setConnectTimeout(3000); //连接等待时间超过三秒则判断图片加载失败 conn.setRequestMethod("GET"); conn.connect(); contentType = conn.getContentType(); is = conn.getInputStream(); if(is == null){ LogUtils.w(this.getClass(), "error loadImage getInputStream is null:" + imageUrl); return null; } if (contentType == null || !contentType.startsWith("image/")) { LogUtils.w(this.getClass(), "error loadImage ContentType:" + contentType + ",url:" + imageUrl); } if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { //drawable = Drawable.createFromStream(is, null); int contentLength = conn.getContentLength(); if(contentLength < 0){ LogUtils.w(this.getClass(), "error loadImage ContentLength:" + contentLength + ",url:" + imageUrl); }else{ byte[] temp = new byte[contentLength]; int len = is.read(temp); drawable = Drawable.createFromStream(new ByteArrayInputStream(temp), null); LogUtils.d(this.getClass(), "loadImage ContentLength:"+contentLength+",length:"+len+",url:"+imageUrl); // drawable = Drawable.createFromStream(is, null); } } else { LogUtils.w(this.getClass(), "loadImage (" + imageUrl + ") fail,ResponseCode:" + conn.getResponseCode()); } if(is != null) is.close(); } catch (Exception e) { if (Constants.DEVELOP) { // e.printStackTrace(); } LogUtils.e(this.getClass(), e.getLocalizedMessage()); }finally{ if(conn != null){ conn.disconnect(); } } return drawable; }
说奇怪是因为 加载图片失败不是某个特别的图片 而是很随机的某张图片。
纠结了两天还是找不到原因,最终改为了网上的这样:
public Drawable loadImageFromUrl(String imageUrl) { LogUtils.d(this.getClass(), "start loadImage:(" + imageUrl + ") "); InputStream input = null; Drawable drawable = null; try { input = new URL(imageUrl).openStream(); if ( input == null) { return null; } drawable = Drawable.createFromStream(input, "src"); } catch (Exception e) { e.printStackTrace(); }finally{ if(input != null){ try { input.close(); } catch (IOException e) { e.printStackTrace(); } } } return drawable; }
代码简单了很多。。。 虽然偶尔也出现图片加载失败的情况,但已经大大减少了出现的概率了。
具体原因不明。。。。
经过再次测试,发现和服务器的响应速度以及手机自身的网速有关。经过google搜索后,代码修改如下
public Drawable loadImageFromUrl(String imageUrl) { Log.d(AsyncImageLoader.class.getName(), "start loadImage:(" + imageUrl + ") "); ByteArrayOutputStream out = null; Drawable drawable = null; int BUFFER_SIZE = 1024*16; try { BufferedInputStream in = new BufferedInputStream(new URL(imageUrl).openStream(),BUFFER_SIZE); out = new ByteArrayOutputStream(BUFFER_SIZE); int length = 0; byte[] tem = new byte[BUFFER_SIZE]; length = in.read(tem); while(length != -1){ out.write(tem, 0, length); //Log.d(AsyncImageLoader.class.getName(), "size:"+out.size()+",url:"+imageUrl); length = in.read(tem); } in.close(); drawable = Drawable.createFromStream(new ByteArrayInputStream(out.toByteArray()), "src"); } catch (Exception e) { Log.e(this.getClass().getName(), ""+e.getClass().getName()+":"+e.getLocalizedMessage()); } return drawable; }
即先读取出图片的全部字节,然后再进行其他的操作。 经测试OK 不会再出现图片加载失败的情况了,就是不知道会不会引起内存溢出