一、内存缓存(一级)
public class MemoryCacheUtils {
存放图片的集合
private HashMap<String,SoftReference<Bitmap>> mHashMap =new HashMap<>();
设置一级缓存(原理)
public void setMemoryCache(String url, Bitmap bitmap){
SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);
mHashMap.put(url,softReference);
mLruCache.put(url,bitmap);
}
获取一级缓存(原理)
public Bitmap getMemoryCache(String url){
SoftReference<Bitmap> softReference =mHashMap.get(url);
if(softReference != null){
Bitmap bitmap =softReference.get();
return bitmap;
}
return null;
return mLruCache.get(url);
}
}
优化:使用LruCache算法(least recentlly used cache),告别软引用和弱引用,内部核心是通过算法实现缓存的大小控制,封装HashMap,使用更加方便简单。使用LruCache代替上述的HashMap。
private LruCache<String,Bitmap> mLruCache;
构造方法初始化LruCache
public MemoryCacheUtils(){
//获取虚拟机分配的最大内存,默认16M
long maxMemory = Runtime.getRuntime().maxMemory();
//参数是内存缓存上限
mLruCache =new LruCache((int) (maxMemory/8)){
@Override
protected int sizeOf(String key, Bitmap value) {
//获取单个对象占用字节数大小
//int byteCount = value.getByteCount();
//兼容低版本,一行字节数*总行数
int byteCount =value.getRowBytes()*value.getHeight();
//返回单个对象占用内存大小
return byteCount;
}
};
二、本地缓存(二级)
public class LocalCacheUtils {
需要存放本地缓存的目录路径
String path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/自定义/";
设置本地缓存
public void setLocalCache(String url, Bitmap bitmap) {
File dir =new File(path);
if (!dir.exists() || !dir.isDirectory()) { // 不存在 或者 不是目录
//创建此抽象路径名指定的目录 //dir.mkdir();
//创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
dir.mkdirs();
}
//url需要经过处理
File file =new File(dir, url);
//将图片压缩到本地
try {
//参数1是图片格式,参数2是压缩比(0-100),100代表不压缩,参数3是文件输出流 bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
}catch (FileNotFoundException e) {
e.printStackTrace();
}
}
获取本地缓存
public Bitmap getLocalCache(String url) {
//url需要经过处理
try {
File cacheFile =new File(path, url);
if (cacheFile.exists()) { //缓存存在
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(cacheFile));
return bitmap;
}
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
三、网络缓存(三级)
public class NetCacheUtils {
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils;
public NetCacheUtils(MemoryCacheUtils memoryCacheUtils,LocalCacheUtils localCacheUtils) {
mMemoryCacheUtils=memoryCacheUtils;
mLocalCacheUtils=localCacheUtils;
}
获取网络图片
public void getBitmapFromNet(ImageView imageView,String url){
new BitmapTask().execute(imageView,url);
}
异步加载网络图片的内部类
class BitmapTaskextends AsyncTask<Object,Void,Bitmap>{
private ImageView mImageView;
@Override
protected void onPreExecute() { //预操作
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Object... params) {//耗时操作
//根据异步加载时传入的参数顺序来获取参数
mImageView = (ImageView) params[0];
String url = (String) params[1];
//防止网络慢时,控件与加载的图片显示不符(ListView)
mImageView.setTag(url);
//网络访问
download(url);
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) { //后续操作
doInBackground返回的值作为参数传入本方法
if(bitmap!=null){
mImageView.setImageBitmap(bitmap);
String url= (String)mImageView.getTag();
写入本地缓存
mLocalCacheUtils.setLocalCache(url,bitmap);
写入内存缓存
mMemoryCacheUtils.setMemoryCache(url,bitmap);
}
}
}
}
四、三级缓存综合使用
public class BitmapUtils {
private NetCacheUtils mNetCacheUtils;
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils;
public BitmapUtils(){
mMemoryCacheUtils =new MemoryCacheUtils();
mLocalCacheUtils =new LocalCacheUtils();
mNetCacheUtils =new NetCacheUtils(mMemoryCacheUtils,mLocalCacheUtils);
}
通过优先级加载图片
public void displayBitmap(ImageView imageView,String url){
内存缓存
Bitmap bitmap=mMemoryCacheUtils.getMemoryCache(url);
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
return;
}
本地缓存
Bitmap bitmap1=mLocalCacheUtils.getLocalCache(url);
if(bitmap1!=null){
imageView.setImageBitmap(bitmap1);
mMemoryCacheUtils.setMemoryCache(url,bitmap1);
return;
}
网络缓存
mNetCacheUtils.getBitmapFromNet(imageView,url);
}
}
五、Android之四大引用
简介:Java虚拟机存在栈和堆,栈存放变量,堆存放类,它们之间存在一种引用关系
1、强引用:默认都是强引用,不会回收
2、软引用:当内存不足时,垃圾回收器会考虑回收
创建:SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);
从软引用中取出:Bitmap bitmap =softReference.get();
3、弱引用:当内存不足时,垃圾回收器更会考虑回收,
4、虚引用:当内存不足时,垃圾回收器最先考虑回收
5、垃圾:一些没有被引用的对象称之为垃圾