在做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 不会再出现图片加载失败的情况了,就是不知道会不会引起内存溢出