LruCache是一个非常好用的图片缓存工具:

主要做法是:滑动图片时将图片的bitmap缓存在LruCache<String, Bitmap>中,退出程序后将图片缓存进文件中。採用DiskLruCache mDiskLruCache

所以我们必须设置一个图片缓存的地址:

public void setImageCache(){
String strPath = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File sdFile = Environment.getExternalStorageDirectory();
strPath = sdFile.getAbsolutePath() + "/pic/";
File cacheFile = new File(strPath);
if(!cacheFile.exists()){
cacheFile.mkdir();
}
}
else{
String strCacheDir = this.getCacheDir().getAbsolutePath();
strPath = strCacheDir + "/pic/";
}
setCachePath(strPath);
} private void setCachePath(String strPicCachePath){
if(TextUtils.isEmpty(strPicCachePath)){
return;
}
m_strPicCachePath = strPicCachePath;
File cacheFile = new File(strPicCachePath);
if(!cacheFile.exists()){
cacheFile.mkdir();
}
} public String getCacheBmpPath(String strUrl){
if(TextUtils.isEmpty(m_strPicCachePath) || TextUtils.isEmpty(strUrl)){
return "";
}
return m_strPicCachePath + StringUtil.MD5Encode(strUrl) + mFileExName;//".bmp";
}

然后写List的adapter:

	private class ListAdapter extends BaseAdapter implements OnScrollListener {

		protected List<ShopData> items = new ArrayList<ShopData>();
protected static final int FETCH_IMAGE_MSG = 1;
private LruCache<String, Bitmap> mMemoryCache;
protected HashSet<ImageView> mItemsMissingImages = new HashSet<ImageView>();
protected ImageLoaderHandler mHandler;
protected ImageLoader mImageFetcher;
public static final int TIMEOUT = 30000;//超时时间30秒
private DiskLruCache mDiskLruCache; public ListAdapter() {
super();
mHandler = new ImageLoaderHandler();
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int mCacheSize = maxMemory / 8;
// 给LruCache分配1/8 4M
mMemoryCache = new LruCache<String, Bitmap>(mCacheSize) { // 必须重写此方法,来測量Bitmap的大小
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
} }; try {
mDiskLruCache = DiskLruCache
.open(new File(m_strPicCachePath), getAppVersion(MainActivityTest.this), 1, 10 * 1024 * 1024);
} catch (IOException e) {
e.printStackTrace();
} } /**
* 将缓存记录同步到journal文件里。 */
public void fluchCache() {
if (mDiskLruCache != null) {
try {
mDiskLruCache.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
} @Override
public int getCount() {
return items.size();
} @Override
public Object getItem(int position) {
return items.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) { ShopDataTag tag = new ShopDataTag();
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listitem, null);
tag.name = (TextView) convertView.findViewById(R.id.name);
tag.shopInfo = (TextView) convertView.findViewById(R.id.info);
tag.icon = (ImageView) convertView.findViewById(R.id.image_icon);
convertView.setTag(tag);
} else {
tag = (ShopDataTag) convertView.getTag();
} TextView name = tag.name;
TextView info = tag.shopInfo;
ImageView imageView = tag.icon;
ShopData data = items.get(position);
name.setText(data.name);
info.setText(data.info);
imageView.setTag(data.url);
setContactPhoto(data.url, imageView);
return convertView;
} protected void setContactPhoto(String url,ImageView viewToUse) {
if(TextUtils.isEmpty(url)) {
viewToUse.setImageResource(R.drawable.avatar);
}else{
//先看mMemoryCache里能不能得到bitmap
Bitmap bitmap = mMemoryCache.get(url);
if (bitmap != null) {
viewToUse.setImageBitmap(bitmap);
} else {
Snapshot snapShot = null;
FileDescriptor fileDescriptor = null;
FileInputStream fileInputStream = null;
try {
//由于mDiskLruCache会把key作为文件名称。所以把url通过md5转换为key
final String key = hashKeyForDisk(url);
snapShot = mDiskLruCache.get(key);
//假设snapShot为空,就是没找到相应的文件
if (snapShot == null) {
//这里去下载
fetchImage(viewToUse);
}else{
fileInputStream = (FileInputStream) snapShot.getInputStream(0);
fileDescriptor = fileInputStream.getFD();
if (fileDescriptor != null) {
bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
}
//假设解析文件成bitmap失败。又一次下载
if(!TextUtils.isEmpty(url) && bitmap != null){
mMemoryCache.put(url, bitmap);
viewToUse.setImageBitmap(bitmap);
}else{
fetchImage(viewToUse);
}
}
}catch(IOException ex) {
ex.printStackTrace();
}finally{
if (fileDescriptor == null && fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
}
}
} }
}
} private void fetchImage(ImageView viewToUse) {
viewToUse.setImageResource(R.drawable.avatar);
mItemsMissingImages.add(viewToUse);
if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
sendFetchImageMessage(viewToUse);
}
} public String <strong>hashKeyForDisk</strong>(String key) { 将key转换为md5文件
return StringUtil.MD5Encode(key);
} // image downloader
private class ImageLoaderHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (isFinishing()) {
return;
}
switch (message.what) {
case FETCH_IMAGE_MSG: {
final ImageView imageView = (ImageView) message.obj;
if (imageView == null) {
break;
} final String url = (String) imageView.getTag();
if (TextUtils.isEmpty(url)) {
break;
} Bitmap map = getBitmapFromMemCache(url);
if (map == null) {
break;
} synchronized (imageView) {
final String myUrl = (String) imageView.getTag();
if (TextUtils.equals(url, myUrl)) {
imageView.setImageBitmap(map);
mItemsMissingImages.remove(imageView);
} else {
}
}
break;
}
}
} public void clearImageFecthing() {
removeMessages(FETCH_IMAGE_MSG);
}
} private class ImageLoader implements Runnable {
String url;
private ImageView mImageView; public ImageLoader(String url, ImageView imageView) {
this.url = url;
this.mImageView = imageView;
} public void run() {
if (isFinishing()) {
return;
} if (Thread.interrupted()) {
return;
} FileDescriptor fileDescriptor = null;
FileInputStream fileInputStream = null;
Snapshot snapShot = null;
try {
final String key = hashKeyForDisk(url);
snapShot = mDiskLruCache.get(key);
if (snapShot == null) {
// 假设没有找到相应的缓存,则准备从网络上请求数据。并写入缓存
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
boolean flag = downloadImage(url, outputStream);
if (flag) {
editor.commit();
} else {
editor.abort();
}
}
// 缓存被写入后,再次查找key相应的缓存
snapShot = mDiskLruCache.get(key);
}
//这里应该删除相应的文件 if (snapShot != null) {
fileInputStream = (FileInputStream) snapShot.getInputStream(0);
fileDescriptor = fileInputStream.getFD();
} // 将缓存数据解析成Bitmap对象
Bitmap bitmap = null;
if (fileDescriptor != null) {
bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
}
if (bitmap != null) {
// 将Bitmap对象加入到内存缓存其中
mMemoryCache.put(url, bitmap);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileDescriptor == null && fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
}
}
} if (Thread.interrupted()) {
return;
} Message msg = new Message();
msg.what = FETCH_IMAGE_MSG;
msg.obj = mImageView;
mHandler.sendMessage(msg);
}
} public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
} public boolean downloadImage(String strUrl,OutputStream fos) { URL getUrl = null;
Bitmap bitmap = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
try {
getUrl = new URL(strUrl);
} catch (MalformedURLException ex) {
Log.e("HttpUtil", "get MalformedURL", ex);
return false;
}
InputStream input = null;
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection)getUrl.openConnection();
conn.setConnectTimeout(TIMEOUT);
conn.setReadTimeout(TIMEOUT);
conn.setDoInput(true);
conn.connect();
input = conn.getInputStream();
in = new BufferedInputStream(input, 8 * 1024);
out = new BufferedOutputStream(fos, 8 * 1024);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
return true;
} catch (Exception ex) {
Log.e("HttpUtil", "downloadImage", ex);
} catch(OutOfMemoryError ex){
ex.printStackTrace();
} finally {
try {
if(out != null){
out.close();
out = null;
}
if (in != null){
in.close();
in = null;
}
if (conn != null){
conn.disconnect();
conn = null;
}
} catch (Exception ex) {
Log.e("HttpUtil", "downloadImage finally", ex);
}
}
return false;
} private boolean getResponse(InputStream input, OutputStream os, byte[] data) throws IOException{
if(input == null || os == null || data == null){
return false;
}
int i = 0;
while( (i = input.read(data)) != -1){
os.write(data, 0, i);
os.flush();
}
os.flush();
return true;
} private void processMissingImageItems(AbsListView view) {
for (ImageView iv : mItemsMissingImages) {
sendFetchImageMessage(iv);
}
} protected void sendFetchImageMessage(ImageView view) {
final String url = (String) view.getTag();
if (TextUtils.isEmpty(url)) {
return;
}
mImageFetcher = new ImageLoader(url, view);
synchronized (MainActivityTest.this) {
if (sImageFetchThreadPool == null) {
sImageFetchThreadPool = Executors.newFixedThreadPool(3);
}
sImageFetchThreadPool.execute(mImageFetcher);
}
} public void clearImageFetching() {
synchronized (MainActivityTest.this) {
if (sImageFetchThreadPool != null) {
sImageFetchThreadPool.shutdownNow();
sImageFetchThreadPool = null;
}
} mHandler.clearImageFecthing();
} public void clearMessages() {
if (mHandler != null) {
try {
mHandler.removeCallbacksAndMessages(null);
} catch (java.lang.Throwable th) {
}
mHandler = null;
}
} @Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
mScrollState = scrollState;
if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
clearImageFetching();
} else {
processMissingImageItems(view);
}
} @Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } } private class ShopDataTag {
TextView name;
TextView shopInfo;
ImageView icon;
}

效果图:

代码:http://download.csdn.net/detail/baidu_nod/7777137

使用LruCache和DiskLruCache来下载图片的更多相关文章

  1. 安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  2. 综合使用LruCache和DiskLruCache 缓存图片

    Activity public class MainActivity extends Activity {     private GridView mPhotoWall;     private P ...

  3. Android Volley框架的使用(四)图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  4. Android照片墙完整版,的完美结合LruCache和DiskLruCache

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/34093441 在上一篇文章其中,我们学习了DiskLruCache的概念和基本使用 ...

  5. 使用lrucache和diskLrucache实现照片墙

    其实,在真正的项目实战当中如果仅仅是使用硬盘缓存的话,程序是有明显短板的.而如果只使用内存缓存的话,程序当然也会有很大的缺陷.因此,一个优秀的程序必然会将内存缓存和硬盘缓存结合到一起使用,那么本篇文章 ...

  6. Android照片墙完整版,完美结合LruCache和DiskLruCache

    转载地址:http://blog.csdn.net/guolin_blog/article/details/34093441#comments 在上一篇文章当中,我们学习了DiskLruCache的概 ...

  7. 网络图片的获取以及二级缓存策略(Volley框架+内存LruCache+磁盘DiskLruCache)

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  8. C++根据图片url下载图片

    需要使用到URLDownloadToFile()函数,该函数在头文件<urlmon.h>中声明. URLDownloadToFile()函数的定义如下: HRESULT URLDownlo ...

  9. .net 已知图片的网络路径,通过浏览器下载图片

    没什么技术含量,主要留给自己查找方便: 如题,知道图片的完整网络路径的情况下,在浏览器中下载图片的实现: 下面这个方法实现的是把图片读取为byte数组: private byte[] GetImage ...

随机推荐

  1. 搭建ss总结

    今天晚上做的事情: 1. https://www.vultr.com/ 购买vps 2. ssh连接到服务器 参照网上帖子安装 https://blog.csdn.net/littlepig19930 ...

  2. UVA-1602 Lattice Animals 搜索问题(打表+set)

    题目链接 https://vjudge.net/problem/UVA-1602 紫书的一道例题,跟之前的很多题目有很多不同. 本题不像是一般的dfs或bfs这样的搜索套路,而是另一种枚举思路. 题意 ...

  3. 单机Mongo复制集安装配置(数据库版本:4.x)

      官方文档: https://docs.mongodb.com/manual/tutorial/deploy-replica-set-with-keyfile-access-control/#dep ...

  4. linux下安装jdk跟tomcat

    文章参考    https://www.cnblogs.com/geekdc/p/5607100.html   Linux服务器安装jdk+tomcat https://baijiahao.baidu ...

  5. Camera Calibration 相机标定:原理简介(四)

    4 基于3D标定物的标定方法 使用基于3D标定物进行相机标定,是一种传统且常见的相机标定法.3D标定物在不同应用场景下不尽相同,摄影测量学中,使用的3D标定物种类最为繁杂,如图-1的室内控制场,由多条 ...

  6. ubuntu鼠标和触摸板的禁用

    ubuntu鼠标和触摸板的禁用 学习了:http://www.2cto.com/os/201308/239403.html 在终端下直接执行以下命令来打开或关闭触摸板. sudo modprobe - ...

  7. hdu 5277 YJC counts stars

    hdu 5277 YJC counts stars 题意: 给出一个平面图,n个点,m条边,直线边与直线边之间不相交,求最大团的数目. 限制: 1 <= n <= 1000 思路: 因为平 ...

  8. github git.exe位置

    C:\Users\yourname\AppData\Local\GitHub\PortableGit_69703d1db91577f4c666e767a6ca5ec50a48d243\bin\git. ...

  9. 转--配置linux下dircolors,ls命令和mac下iTerm2的颜色,让终端(iTerm2或Terminal)也色彩缤纷

    http://blog.bbkanba.com/%E9%85%8D%E7%BD%AElinux%E4%B8%8Bdircolorsls%E5%91%BD%E4%BB%A4%E5%92%8Cmac%E4 ...

  10. Delphi的时间 x87 fpu control word 精度设置的不够

    在win7 64位系统下, 一个DELPHI写的DLL注入一个C语言程序后. 出现非常奇怪的浮点数相加出错的情况. (注: 在XP系统下是正常的).比如: 40725.0001597563 + 0.7 ...