这是一篇关于Android ListView异步加载图片的文章,下面是精品为您提供的一些内容,希望对您有所帮助
对于ListView,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求。。。
常见的ListView中很少全是文字的,一般都是图文共存的,而图片的来源是服务器端(很少有写在客户端的吧。。。考虑客户端的大小和更新的问题),所以,网络问题就成了图片是否能顺利加载成功的决定性因素了。大家都知道每次启动一个Android应用,都会启动一个UI主线程,主要是响应用户的交互,如果我们把不确定的获取网络图片的操作放在UI主线程,结果也就不确定了。。。当然,如果你网络足够好的话,应该问题不大,但是,网络谁能保证呢?所以就出现了“异步加载”的方法!
我先叙述一下异步加载的原理,说的通俗一点就是UI主线程继续做与用户交互的响应监听和操作,而加载图片的任务交到其他线程中去做,当图片加载完成之后,再跟据某种机制(比如回调)绘制到要显示的控件中。
首先,贴出AsyncBitmapLoader.java,这个类是关键,主要做的就是当加载图片的时候,去缓冲区查找,如果有的话,则立刻返回Bitmap对象,省掉再去网络服务器下载的时间和流量。
[java]
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import onerain.ald.common.HttpUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
/**
* @author oneRain
**/
public class AsyncBitmapLoader
{
/**
* 内存图片软引用缓冲
*/
private HashMap> imageCache = null;
public AsyncBitmapLoader()
{
imageCache = new HashMap>();
}
public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)
{
//在内存缓存中,则返回Bitmap对象
if(imageCache.containsKey(imageURL))
{
SoftReference reference = imageCache.get(imageURL);
Bitmap bitmap = reference.get();
if(bitmap != null)
{
return bitmap;
}
}
else
{
/**
* 加上一个对本地缓存的查找
*/
String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);
File cacheDir = new File("/mnt/sdcard/test/");
File[] cacheFiles = cacheDir.listFiles();
int i = 0;
for(; i
{
if(bitmapName.equals(cacheFiles[i].getName()))
{
break;
}
}
if(i < cacheFiles.length)
{
return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);
}
}
final Handler handler = new Handler()
{
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);
}
};
//如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片
new Thread()
{
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run()
{
// TODO Auto-generated method stub
InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);
Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);
imageCache.put(imageURL, new SoftReference(bitmap));
Message msg = handler.obtainMessage(0, bitmap);
handler.sendMessage(msg);
File dir = new File("/mnt/sdcard/test/");
if(!dir.exists())
{
dir.mkdirs();
}
File bitmapFile = new File("/mnt/sdcard/test/" +
imageURL.substring(imageURL.lastIndexOf("/") + 1));
if(!bitmapFile.exists())
{
try
{
bitmapFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
FileOutputStream fos;
try
{
fos = new FileOutputStream(bitmapFile);
bitmap.compress(Bitmap.CompressFormat.JPEG,
100, fos);
fos.close();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
return null;
}
/**
* 回调接口
* @author onerain
*
*/
public interface ImageCallBack
{
public void imageLoad(ImageView imageView, Bitmap bitmap);
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import onerain.ald.common.HttpUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
/**
* @author oneRain
**/
public class AsyncBitmapLoader
{
/**
* 内存图片软引用缓冲
*/
private HashMap> imageCache = null;
public AsyncBitmapLoader()
{
imageCache = new HashMap>();
}
public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)
{
//在内存缓存中,则返回Bitmap对象
if(imageCache.containsKey(imageURL))
{
SoftReference reference = imageCache.get(imageURL);
Bitmap bitmap = reference.get();
if(bitmap != null)
{
return bitmap;
}
}
else
{
/**
* 加上一个对本地缓存的查找
*/
String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);
File cacheDir = new File("/mnt/sdcard/test/");
File[] cacheFiles = cacheDir.listFiles();
int i = 0;
for(; i
{
if(bitmapName.equals(cacheFiles[i].getName()))
{
break;
}
}
if(i < cacheFiles.length)
{
return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);
}
}
final Handler handler = new Handler()
{
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);
}
};
//如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片
new Thread()
{
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run()
{
// TODO Auto-generated method stub
InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);
Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);
imageCache.put(imageURL, new SoftReference(bitmap));
Message msg = handler.obtainMessage(0, bitmap);
handler.sendMessage(msg);
File dir = new File("/mnt/sdcard/test/");
if(!dir.exists())
{
dir.mkdirs();
}
File bitmapFile = new File("/mnt/sdcard/test/" +
imageURL.substring(imageURL.lastIndexOf("/") + 1))