`
酷的飞上天空
  • 浏览: 521858 次
  • 性别: 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
分享到:
评论

相关推荐

    异步加载网络图片

    缓存机制是异步加载图片中的重要组成部分,分为内存缓存和磁盘缓存。内存缓存能快速响应图片请求,但当内存不足时会被系统回收。磁盘缓存则可以长期保存图片,即使应用关闭后仍能复用,但读取速度相对较慢。通过合理...

    listview 异步加载网络图片

    在ListView中使用Glide,可以在Adapter的getView方法中调用Glide.with(context).load(url).into(imageView)来加载图片。Glide会自动管理图片的生命周期,防止内存泄漏。 4. **缓存机制**:异步加载的同时,利用本地...

    Android 图片异步加载 加载网络图片

    在Android应用开发中,图片加载是一项常见的任务,尤其是在处理大量图片或者网络图片时,为了提供良好的用户体验,我们通常会采用异步加载的方式。本篇将深入探讨Android平台上的图片异步加载策略,以及如何加载网络...

    android异步加载网络图片实例

    Fresco 使用自己的内存和磁盘缓存系统,不会占用应用的内存,可以避免因加载图片导致的OOM(Out of Memory)问题。 7. **图片缓存策略**: 无论是哪种库,缓存策略都是必不可少的。内存缓存用于快速响应,而磁盘...

    Android异步加载网络图片

    它能够流畅地处理图片的加载、缩放以及动画过渡,非常适合在滚动列表中加载图片。 8. ** Fresco库** - Facebook的Fresco库为大型图片和复杂图像处理提供了强大的解决方案,它使用了SurfaceView和内存管理技术,...

    android Gallery实现异步加载网络图片 并只加载当前停止页面图.zip

    然后,我们需要创建一个自定义的`Gallery`适配器,这个适配器会负责获取每个图片的URL,并使用`Glide`异步加载图片: ```java public class ImageAdapter extends BaseAdapter { private Context context; ...

    图片异步加载,照片墙,异步加载listview图片2

    因此,异步加载图片是必要的,它可以在后台线程中处理图片下载和解码工作,保持UI流畅。 2. ListView与异步加载: ListView是一个常用的组件,用于展示可滚动的列表数据。每个列表项可能包含图片。当用户滚动时,...

    iOS异步加载网络图片Demo代码

    一个iOS异步加载网络图片的Demo,用Objective-C写的,包含了三种加载网络图片的方式:同步、异步和Cache异步。界面布局全部代码手写,使用的是TableView布局。代码有注释,很简洁。欢迎大家下载使用。

    GridView异步加载网络图片

    GridView的适配器(如BaseAdapter或ArrayAdapter)需要扩展以包含异步加载图片的功能。在getView()方法中,启动异步任务加载图片,并在图片加载完成后更新ImageView。 4. **缓存策略** 为了提高性能和减少网络...

    android Gallery实现异步加载网络图片

    android Gallery实现异步加载网络图片 并只加载当前停止页面图

    android Gridview 异步加载网络图片

    2. ** 异步加载图片的重要性** - 直接在主线程加载网络图片会导致应用卡顿,用户体验下降,因为主线程负责处理用户交互和UI更新。 - 异步加载是在后台线程执行耗时操作,如下载和解码图片,然后在主线程更新UI,...

    wpf 异步加载图片完成后再显示,失败则显示本地图片

    在WPF应用开发中,异步加载图片是一个常见的需求,特别是在处理大尺寸或者网络资源时,为了提升用户体验,我们希望图片加载不影响界面的响应速度。本文将深入探讨如何实现这一功能,并在加载失败时切换到本地备份...

    iOS从网络异步加载图片

    在iOS开发中,高效地从网络加载图片是用户体验的关键因素之一。本篇文章将详细探讨如何利用第三方库TBXML进行XML解析以及使用IconDownloader实现图片的异步加载。 首先,我们来了解一下TBXML(Tiny Binary XML)。...

    wpf 异步加载图片完成后再显示

    在WPF(Windows Presentation Foundation)应用开发中,异步加载图片是提高用户体验的关键技术,特别是在处理大尺寸或者网络延迟较大的情况下。本知识点将详细讲解如何实现wpf异步加载图片并在加载完成后显示。 ...

    Android异步加载图片例子

    在Android开发中,异步加载图片是一项至关重要的技术,尤其对于那些包含大量图像的移动应用而言,如社交网络、电商应用等。异步加载能够提高用户体验,避免UI线程阻塞,防止应用出现"卡死"现象。在这个"Android异步...

    GridView异步加载大量网络图片

    在加载图片时,应根据ImageView的大小进行合适的解码,避免加载全尺寸图片。 4. 使用第三方库:有许多优秀的开源库可以帮助我们更高效地实现图片异步加载,例如Picasso、Glide和Fresco。这些库已经考虑到了许多优化...

    ListView异步加载网络图片

    2. 当需要加载图片时,首先检查HashMap中是否存在对应的SoftReference。如果存在且Bitmap未被回收,直接返回Bitmap;否则,启动一个新的后台任务下载图片。 3. 后台任务下载图片完成后,利用SoftReference将Bitmap...

    Android平台的图像控件,可以异步加载网络图片、项目资源和本地图片,并且支持双指缩放、图片的基本处理.zip

    Android平台的图像控件,可以异步加载网络图片、项目资源和本地图片,并且支持双指缩放、图片的基本处理 Android平台的图像控件,可以异步加载网络图片、项目资源和本地图片,并且支持双指缩放、图片的基本处理 ...

    lazyload异步加载图片

    **懒加载(Lazy Load)异步加载图片技术详解** 懒加载是一种优化网页性能的技术,它主要应用于图片或者视频等大体积资源的加载。在网页初次加载时,只加载视口内的图片,当用户滚动页面,即将进入视口的图片才会被...

    Handler结合thread 异步加载网络图片

    在Android开发中,异步加载网络图片是一项常见的需求,它能提高应用的用户体验,避免主线程因处理耗时操作而卡顿。本示例通过Handler和Thread的配合,实现了一个简单的网络图片异步加载功能。这里我们将深入探讨这两...

Global site tag (gtag.js) - Google Analytics