在做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 不会再出现图片加载失败的情况了,就是不知道会不会引起内存溢出
分享到:
相关推荐
缓存机制是异步加载图片中的重要组成部分,分为内存缓存和磁盘缓存。内存缓存能快速响应图片请求,但当内存不足时会被系统回收。磁盘缓存则可以长期保存图片,即使应用关闭后仍能复用,但读取速度相对较慢。通过合理...
在ListView中使用Glide,可以在Adapter的getView方法中调用Glide.with(context).load(url).into(imageView)来加载图片。Glide会自动管理图片的生命周期,防止内存泄漏。 4. **缓存机制**:异步加载的同时,利用本地...
在Android应用开发中,图片加载是一项常见的任务,尤其是在处理大量图片或者网络图片时,为了提供良好的用户体验,我们通常会采用异步加载的方式。本篇将深入探讨Android平台上的图片异步加载策略,以及如何加载网络...
Fresco 使用自己的内存和磁盘缓存系统,不会占用应用的内存,可以避免因加载图片导致的OOM(Out of Memory)问题。 7. **图片缓存策略**: 无论是哪种库,缓存策略都是必不可少的。内存缓存用于快速响应,而磁盘...
它能够流畅地处理图片的加载、缩放以及动画过渡,非常适合在滚动列表中加载图片。 8. ** Fresco库** - Facebook的Fresco库为大型图片和复杂图像处理提供了强大的解决方案,它使用了SurfaceView和内存管理技术,...
然后,我们需要创建一个自定义的`Gallery`适配器,这个适配器会负责获取每个图片的URL,并使用`Glide`异步加载图片: ```java public class ImageAdapter extends BaseAdapter { private Context context; ...
因此,异步加载图片是必要的,它可以在后台线程中处理图片下载和解码工作,保持UI流畅。 2. ListView与异步加载: ListView是一个常用的组件,用于展示可滚动的列表数据。每个列表项可能包含图片。当用户滚动时,...
一个iOS异步加载网络图片的Demo,用Objective-C写的,包含了三种加载网络图片的方式:同步、异步和Cache异步。界面布局全部代码手写,使用的是TableView布局。代码有注释,很简洁。欢迎大家下载使用。
GridView的适配器(如BaseAdapter或ArrayAdapter)需要扩展以包含异步加载图片的功能。在getView()方法中,启动异步任务加载图片,并在图片加载完成后更新ImageView。 4. **缓存策略** 为了提高性能和减少网络...
android Gallery实现异步加载网络图片 并只加载当前停止页面图
2. ** 异步加载图片的重要性** - 直接在主线程加载网络图片会导致应用卡顿,用户体验下降,因为主线程负责处理用户交互和UI更新。 - 异步加载是在后台线程执行耗时操作,如下载和解码图片,然后在主线程更新UI,...
在WPF应用开发中,异步加载图片是一个常见的需求,特别是在处理大尺寸或者网络资源时,为了提升用户体验,我们希望图片加载不影响界面的响应速度。本文将深入探讨如何实现这一功能,并在加载失败时切换到本地备份...
在iOS开发中,高效地从网络加载图片是用户体验的关键因素之一。本篇文章将详细探讨如何利用第三方库TBXML进行XML解析以及使用IconDownloader实现图片的异步加载。 首先,我们来了解一下TBXML(Tiny Binary XML)。...
在WPF(Windows Presentation Foundation)应用开发中,异步加载图片是提高用户体验的关键技术,特别是在处理大尺寸或者网络延迟较大的情况下。本知识点将详细讲解如何实现wpf异步加载图片并在加载完成后显示。 ...
在Android开发中,异步加载图片是一项至关重要的技术,尤其对于那些包含大量图像的移动应用而言,如社交网络、电商应用等。异步加载能够提高用户体验,避免UI线程阻塞,防止应用出现"卡死"现象。在这个"Android异步...
在加载图片时,应根据ImageView的大小进行合适的解码,避免加载全尺寸图片。 4. 使用第三方库:有许多优秀的开源库可以帮助我们更高效地实现图片异步加载,例如Picasso、Glide和Fresco。这些库已经考虑到了许多优化...
2. 当需要加载图片时,首先检查HashMap中是否存在对应的SoftReference。如果存在且Bitmap未被回收,直接返回Bitmap;否则,启动一个新的后台任务下载图片。 3. 后台任务下载图片完成后,利用SoftReference将Bitmap...
Android平台的图像控件,可以异步加载网络图片、项目资源和本地图片,并且支持双指缩放、图片的基本处理 Android平台的图像控件,可以异步加载网络图片、项目资源和本地图片,并且支持双指缩放、图片的基本处理 ...
**懒加载(Lazy Load)异步加载图片技术详解** 懒加载是一种优化网页性能的技术,它主要应用于图片或者视频等大体积资源的加载。在网页初次加载时,只加载视口内的图片,当用户滚动页面,即将进入视口的图片才会被...
在Android开发中,异步加载网络图片是一项常见的需求,它能提高应用的用户体验,避免主线程因处理耗时操作而卡顿。本示例通过Handler和Thread的配合,实现了一个简单的网络图片异步加载功能。这里我们将深入探讨这两...