首先简单说一下:
三级缓存有哪三级:
1、网络缓存 从网络获取资源(异步加载)网络缓存, 不优先加载, 速度慢,浪费流量
2、本地缓存 从本地获取数据(File存储)本地缓存, 次优先加载, 速度快
3、内存缓存 从内存获取数据(LruCache) 内存缓存, 优先加载, 速度最快
好了,下面回归咱们的正题,直接代码搞起
本地缓存
public class LocalCacheUtils {
private static final String CACHE_PATH= Environment.getExternalStorageDirectory().getAbsolutePath()+"/my/images";
/**
* 从本地读取图片
* @param url
*/
public Bitmap getBitmapFromLocal(String url){
String fileName = null;//把图片的url当做文件名,并进行MD5加密
try {
File file=new File(CACHE_PATH,fileName);
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 从网络获取图片后,保存至本地缓存
* @param url
* @param bitmap
*/
public void setBitmapToLocal(String url,Bitmap bitmap){
try {
File file=new File(CACHE_PATH,url);
//通过得到文件的父文件,判断父文件是否存在
File parentFile = file.getParentFile();
if (!parentFile.exists()){
parentFile.mkdirs();
}
//把图片保存至本地
bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
} catch (Exception e) {
e.printStackTrace();
}
}
}
内存缓存
public class MemoryCacheUtils {
private LruCache<String, Bitmap> mMemoryCache;
public MemoryCacheUtils(){
long maxMemory = Runtime.getRuntime().maxMemory()/8;//得到手机最大允许内存的1/8,即超过指定内存,则开始回收
//需要传入允许的内存最大值,虚拟机默认内存16M,真机不一定相同
mMemoryCache=new LruCache<String,Bitmap>((int) maxMemory){
//用于计算每个条目的大小
@Override
protected int sizeOf(String key, Bitmap value) {
int byteCount = value.getByteCount();
return byteCount;
}
};
}
/**
* 从内存中读图片
* @param url
*/
public Bitmap getBitmapFromMemory(String url) {
//Bitmap bitmap = mMemoryCache.get(url);//1.强引用方法
/*2.弱引用方法
SoftReference<Bitmap> bitmapSoftReference = mMemoryCache.get(url);
if (bitmapSoftReference != null) {
Bitmap bitmap = bitmapSoftReference.get();
return bitmap;
}
*/
if(url==null||"".equals(url)){
return null;
}
Bitmap bitmap = mMemoryCache.get(url);
return bitmap;
}
/**
* 往内存中写图片
* @param url
* @param bitmap
*/
public void setBitmapToMemory(String url, Bitmap bitmap) {
//mMemoryCache.put(url, bitmap);//1.强引用方法
/*2.弱引用方法
mMemoryCache.put(url, new SoftReference<>(bitmap));
*/
mMemoryCache.put(url,bitmap);
}
}
网络缓存
public class NetCacheUtils {
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils;
public NetCacheUtils(LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) {
mLocalCacheUtils = localCacheUtils;
mMemoryCacheUtils = memoryCacheUtils;
}
public NetCacheUtils(){
}
/**
* 从网络下载图片
* @param ivPic 显示图片的imageview
* @param url 下载图片的网络地址
*/
public void getBitmapFromNet(ImageView ivPic, String url) {
new BitmapTask().execute(ivPic, url);//启动AsyncTask
}
public void getBitmapFromNet(View ivPic, String url) {
new BitmapTask_view().execute(ivPic, url);//启动AsyncTask
}
public Bitmap getBitmapFromNet(final String url) {
//启动AsyncTask
return null;
}
/**
* AsyncTask就是对handler和线程池的封装
* 第一个泛型:参数类型
* 第二个泛型:更新进度的泛型
* 第三个泛型:onPostExecute的返回结果
*/
class BitmapTask extends AsyncTask<Object, Void, Bitmap> {
private ImageView ivPic;
private String url;
/**
* 后台耗时操作,存在于子线程中
* @param params
* @return
*/
@Override
protected Bitmap doInBackground(Object[] params) {
ivPic = (ImageView) params[0];
url = (String) params[1];
return downLoadBitmap(url);
}
/**
* 更新进度,在主线程中
* @param values
*/
@Override
protected void onProgressUpdate(Void[] values) {
super.onProgressUpdate(values);
}
/**
* 耗时方法结束后执行该方法,主线程中
* @param result
*/
@Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
ivPic.setImageBitmap(result);
System.out.println("从网络缓存图片啦.....");
//从网络获取图片后,保存至本地缓存
mLocalCacheUtils.setBitmapToLocal(url, result);
//保存至内存中
mMemoryCacheUtils.setBitmapToMemory(url, result);
}
}
}
/**
* AsyncTask就是对handler和线程池的封装
* 第一个泛型:参数类型
* 第二个泛型:更新进度的泛型
* 第三个泛型:onPostExecute的返回结果
*/
@SuppressLint("NewApi")
class BitmapTask_view extends AsyncTask<Object, Void, Bitmap> {
private View ivPic;
private String url;
/**
* 后台耗时操作,存在于子线程中
* @param params
* @return
*/
@Override
protected Bitmap doInBackground(Object[] params) {
ivPic = (View) params[0];
url = (String) params[1];
return downLoadBitmap(url);
}
/**
* 更新进度,在主线程中
* @param values
*/
@Override
protected void onProgressUpdate(Void[] values) {
super.onProgressUpdate(values);
}
/**
* 耗时方法结束后执行该方法,主线程中
* @param result
*/
@Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
//ivPic.setImageBitmap(result);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//Android系统大于等于API16,使用setBackground
ivPic.setBackground(new BitmapDrawable(result));
} else {
//Android系统小于API16,使用setBackground
ivPic.setBackgroundDrawable(new BitmapDrawable(result));
}
System.out.println("从网络缓存图片啦.....");
//从网络获取图片后,保存至本地缓存
mLocalCacheUtils.setBitmapToLocal(url, result);
//保存至内存中
mMemoryCacheUtils.setBitmapToMemory(url, result);
}
}
}
/**
* 网络下载图片
* @param url
* @return
*/
public Bitmap downLoadBitmap(String url) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
//图片压缩
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize=2;//宽高压缩为原来的1/2
options.inPreferredConfig=Bitmap.Config.ARGB_4444;
//Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream(),null,options);
Bitmap bitmap=BitmapFactory.decodeStream(conn.getInputStream());
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}catch (Exception e) {
} finally {
if(conn!=null){
conn.disconnect();
}
}
return null;
}
}
另写一个类进行调用
public class MyBitmapUtils {
private NetCacheUtils mNetCacheUtils;
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils;
public MyBitmapUtils(){
mMemoryCacheUtils=new MemoryCacheUtils();
mLocalCacheUtils=new LocalCacheUtils();
mNetCacheUtils=new NetCacheUtils(mLocalCacheUtils,mMemoryCacheUtils);
}
public Bitmap getBitmap(String url){
Bitmap bitmap=null;
bitmap=mMemoryCacheUtils.getBitmapFromMemory(url);
if(bitmap!=null){
return bitmap;
}
bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
if(bitmap!=null){
mMemoryCacheUtils.setBitmapToMemory(url,bitmap);
return bitmap;
}
return bitmap;
}
public void disPlay(ImageView ivPic, String url) {
Bitmap bitmap;
//内存缓存
bitmap=mMemoryCacheUtils.getBitmapFromMemory(url);
if (bitmap!=null){
ivPic.setImageBitmap(bitmap);
Log.e("iamgecache","从内存获取图片啦.....--->"+url);
return;
}
//本地缓存
bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
if(bitmap !=null){
ivPic.setImageBitmap(bitmap);
Log.d("iamgecache","从本地获取图片啦.....-->"+url);
//从本地获取图片后,保存至内存中
mMemoryCacheUtils.setBitmapToMemory(url,bitmap);
return;
}
//网络缓存
mNetCacheUtils.getBitmapFromNet(ivPic,url);
Log.d("iamgecache","从网络获取图片啦.....-->"+url);
}
@SuppressLint("NewApi")
public void disPlay(View ivPic, String url) {
Bitmap bitmap;
//内存缓存
bitmap=mMemoryCacheUtils.getBitmapFromMemory(url);
if (bitmap!=null){
//ivPic.setImageBitmap(bitmap);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//Android系统大于等于API16,使用setBackground
ivPic.setBackground(new BitmapDrawable(bitmap));
} else {
//Android系统小于API16,使用setBackground
ivPic.setBackgroundDrawable(new BitmapDrawable(bitmap));
}
//ivPic.setBackground(new BitmapDrawable(bitmap));
Log.d("iamgecache","从内存获取图片啦.....--->"+url);
return;
}
//本地缓存
bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
if(bitmap !=null){
// ivPic.setImageBitmap(bitmap);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//Android系统大于等于API16,使用setBackground
ivPic.setBackground(new BitmapDrawable(bitmap));
} else {
//Android系统小于API16,使用setBackground
ivPic.setBackgroundDrawable(new BitmapDrawable(bitmap));
}
//ivPic.setBackground(new BitmapDrawable(bitmap));
Log.e("iamgecache","从本地获取图片啦.....-->"+url);
//从本地获取图片后,保存至内存中
mMemoryCacheUtils.setBitmapToMemory(url,bitmap);
return;
}
//网络缓存
mNetCacheUtils.getBitmapFromNet(ivPic,url);
// ivPic.setBackground(new BitmapDrawable(bitmap));
Log.e("iamgecache","从网络获取图片啦.....-->"+url);
}
}
到这里就可以了,剩下就是在需要的activity的中调用,更多精彩内容大家可以看看我的公众号