您的位置:首页 > 移动开发 > Android开发

Android自制图片的三级缓存(代码+讲解)

2016-03-17 23:07 826 查看

Android的图片三级缓存机制

首先

图片的三计划缓存的概念

泛指的是 -内存缓存 -本地缓存 -网络缓存

内存缓存的概念

应用程序在运行时 WindowMeanger会分配给 应用 相应的运行时内存

运行是内存的大小根据android版本有关系

本地缓存的概念

本地缓存是存储在硬件上的数据

网络缓存的概念

图片存储在网络上,需要下载

小结

这三种缓存的概念以上以及陈述了,既然我们要做一个服务于图片的缓存,那么

我们就要应用起来这三种缓存到 我们的这个 demo里面

要应用它 首先 我们做一下项目规划 这个缓存 每一个缓存都要是个单独的类

保持封装性 然后调用的时候要简单 一行代码就调用

那么我们 还要做一个 proxy

好 下面开始

内存设计代码

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
/**
* LruCache工具类
* @author 浩
*
*/
public class MemoryCacheUtils {

private LruCache<String, Bitmap> lruCache;//集合

public MemoryCacheUtils() {
int maxSize = (int) Runtime.getRuntime().maxMemory();
lruCache = new LruCache<String, Bitmap>(maxSize){

@Override
protected int sizeOf(String key, Bitmap value) {
// TODO Auto-generated method stub
return value.getRowBytes() * value.getHeight();
}

};
}

/**
* 根据url从内存中得到缓存图片
* @param url
* @return
*/
public Bitmap getBitmapFromUril(String url) {
// TODO Auto-generated method stub
return lruCache.get(url);
}

/**
* 根据url,和bitmp在内存中保存一份bitmap
* @param url
* @param bitmap
*/
public void putBitmap2Memory(String url, Bitmap bitmap) {
//每个应用占多少内存:16MB
lruCache.put(url, bitmap);

}

}


本地缓存设计

mport android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.widget.ImageView;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class LocalCacheUtils {
/**
* 本地缓存工具类
*
* @author 王浩
*
*/

private static final String ATGUIT_DIR = "/mnt/sdcard/beijingnews/";

/**
* 根据Bitmap保存图片到本地
*
* @param url
* @param bitmap
*/
public void putBitmap2Local(String url, Bitmap bitmap) {
// TODO Auto-generated method stub
try {
// String name = MD5Encoder.encode(url);
// /mnt/sdcard/beijingnews/lskkskklllkk(md5加密)
File file = new File(ATGUIT_DIR, url);
// mnt/sdcard/beijingnews/创建
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}

// 图片就保存到sdcard了
FileOutputStream stream = new FileOutputStream(file);

bitmap.compress(CompressFormat.JPEG, 100, stream);

stream.close();

} catch (Exception e) {
e.printStackTrace();
}

}

/**
* 根据uri取对应的图片
*
* @param url
* @return
*/
public Bitmap getBitmapFromUrl(String url, ImageView imageView, int tag) {
try {
File file = new File(ATGUIT_DIR, url);
if (file.isFile()) {
Bitmap bitmap = null ;
FileInputStream fis = new FileInputStream(file);
fis.close();
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

}


网络缓存设计

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
* 网络缓存图片的工具类
*
* @author 王浩
*/
public class NetCatchUtils {

/**
* 网络请求图片成功
*/
public static final int SUCESS = 0;
/**
* 网络请求图片失败
*/
public static final int FAIL = 1;
private Handler handler;
/**
* 本地缓存工具类
*/
private LocalCacheUtils localCacheUtils;
/**
* 内存缓存工具
*/
private MemoryCacheUtils memoryCacheUtils;

public NetCatchUtils(Handler handler, LocalCacheUtils localCacheUtils,
MemoryCacheUtils memoryCacheUtils) {
// TODO Auto-generated constructor stub
this.handler = handler;
this.localCacheUtils = localCacheUtils;
this.memoryCacheUtils = memoryCacheUtils;
}

/**
* 根据图片路径,请求网络图片
*
* @param url
* @param position
* @return
*/
public Bitmap getBitmapFromUrl(String url, int position, int tag,
Activity ac, ImageView tv_image) {
new Thread(new MyRunnable(url, position, tag, ac, tv_image)).start();

return null;
}

class MyRunnable implements Runnable {

private String url;
private int position;
private int tag;
private Activity ac;
private ImageView tv_image;

public MyRunnable(String url, int position, int tag, Activity ac,
ImageView tv_image) {

this.url = url;
this.position = position;
this.tag = tag;
this.ac = ac;
this.tv_image = tv_image;
}

/**
* 处理大图片加载问题
*/
@Override
public void run() {
HttpURLConnection con = null;
try {

con = (HttpURLConnection) new
URL(url).openConnection();

int code = con.getResponseCode();

if (200 == code) {
InputStream is = con.getInputStream();

Options opts = new Options();

// 根据计算出的比例进行缩放
int scale = ImageUtils.getScare(url, ac);
opts.inSampleSize = scale;

Bitmap bm = BitmapFactory.decodeStream(is, null, opts);

// 将bm发生给主线程用于显示图片,更新UI
Message msg = Message.obtain();
msg.obj = bm;
msg.arg1 = tag;
msg.arg2 = position;

tv_image.post(new Action(bm, tv_image));
//                    if(handler!=null) {
//                        tv_image.post(new Action(bm, tv_image));
//                        //handler.sendMessage(msg);
//                    } else {
//                        Utils.log2("tv_image:" + bm + "————tv_image:" + tv_image);
//                        //tv_image.setImageBitmap(bm);
//
//
//                    }

// 保存一份在内存
memoryCacheUtils.putBitmap2Memory(url, bm);
// 保存一份在本地(Sdcard)
localCacheUtils.putBitmap2Local(url, bm);

}
} catch (Exception e) {
//                e.printStackTrace();
}

}

}

/**
* 在主线程更新UI
*/
class Action implements Runnable{

private Bitmap  bit ;
private ImageView img  ;

public Action(Bitmap bit,ImageView img) {
this.bit  = bit;
this.img  = img;
}

@Override
public void run() {

img.setImageBitmap(bit);
}
}

}


代理者设计

/**
* 三级缓存工具类
*
* @author wanghao
*
*/
public class ImageCacheProxy {

public static final int LARGE_PHOTO = -11 ;
/**
* 一级本地缓存
*/
LocalCacheUtils localCacheUtils;
/**
* 二级内存缓存
*/
private MemoryCacheUtils memoryCacheUtils;
/**
* 三级网络获取图片
*/
private NetCatchUtils netUtils ;
/**
* 初始化三级缓存
* @param handler
*/
public ImageCacheProxy() {
localCacheUtils = new LocalCacheUtils();
memoryCacheUtils = new MemoryCacheUtils();
netUtils = new NetCatchUtils(null, localCacheUtils, memoryCacheUtils);
}

/**
* @param tv_image 要把bit替换成image的image
* @param url 请求图片的地址
* @param position 给图片做的tag  方便 handler ,里面 去取
* @param tag arg1的标记
*/
public void imageLoader(ImageView tv_image, String url, int position, int tag ,Activity ac) {
Bitmap bit;

bit = localCacheUtils.getBitmapFromUrl(url,tv_image,tag);
if (bit != null) {
tv_image.setImageBitmap(bit);
return;
}
bit = memoryCacheUtils.getBitmapFromUril(url);
if (bit != null) {
tv_image.setImageBitmap(bit);
return;
}
netUtils.getBitmapFromUrl(url, position, tag ,ac,tv_image);
}

}


这就OK了 调用 只需要一行代码loader下 就行了

附上我写的 demo project 地址

https://github.com/mywanghao/twentythreemodule/tree/master/imagecachedemo

这个是一个很多demo的一个集合里面 如果要运行 建议 donwload twentythreemodule这个主 porject

本篇博客结束

如果觉得对你有帮助

粉我把

关注更多我的blog.

技术交流群:

博客圈 493554215

这是一个热爱分享技术,拥有热烈学习氛围的群 ,

博主身为群内的一员感到骄傲

推荐还在路上的伙伴们
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: