`
酷的飞上天空
  • 浏览: 517772 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
社区版块
存档分类
最新评论

纠结了两天的异步加载网络图片问题

阅读更多

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

 

 

0
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics