上一篇博客已经把三级缓存原理大致都讲了,这篇博客就仅仅贴一下封装好的一个图片三级缓存工具类,代码内有注释,仅仅小记一下:
首先是MyBitmapUtils,它提供了一个display方法去供外界调用:
/**
* 图片三级缓存工具类
* Created by PDD on 2018/3/6.
*/
public class MyBitmapUtils {
private NetWorkCacheUtils netWorkCacheUtils;
private MemoryCacheUtils memoryCacheUtils;
private LocalCacheUtils localCacheUtils;
public MyBitmapUtils(Context context){
localCacheUtils=new LocalCacheUtils();
memoryCacheUtils=new MemoryCacheUtils();
netWorkCacheUtils=new NetWorkCacheUtils(context,memoryCacheUtils,localCacheUtils);
}
public void display(ImageView ivPic,String url) {
//给ImageView设置默认显示图片
ivPic.setImageResource(R.drawable.btn_zhifubao);
//创建一个bitmap变量,用于接收从各缓存拿到的图片bitmap
Bitmap bitmap;
//首先从内存获取图片
bitmap = memoryCacheUtils.getBitmapFromMemory(url);
//判断
if (bitmap != null) {
ivPic.setImageBitmap(bitmap);
System.out.println("从内存中获取图片成功");
return;
}
//从内存获取图片失败,再从本地获取图片
bitmap = localCacheUtils.getBitmapFromLocal(url);
//判断
if (bitmap!=null){
ivPic.setImageBitmap(bitmap);
//将从本地获取的图片存到内存中
memoryCacheUtils.setBitmapToMemory(url,bitmap);
System.out.println("从本地获取图片成功");
return;
}
//如果前两种方法都无法获得,那么最后才从网络中获取图片
netWorkCacheUtils.getBitmapFromNet(ivPic,url);
}
}
三级缓存之网络缓存NetWorkCacheUtils,使用HttpUrlConnection
/** * 三级缓存值网络缓存 */public class NetWorkCacheUtils { private MemoryCacheUtils memoryCacheUtils; private LocalCacheUtils localCacheUtils; private Context context; public NetWorkCacheUtils(Context context,MemoryCacheUtils memoryCacheUtils, LocalCacheUtils localCacheUtils){ this.memoryCacheUtils=memoryCacheUtils; this.localCacheUtils=localCacheUtils; this.context=context; } /** * 从网络中下载图片 * @param ivPic 需要显示图片的ImageView * @param url */ public void getBitmapFromNet(ImageView ivPic, String url) { new BitmapTask().execute(ivPic,url); } class BitmapTask extends AsyncTask<Object,Void,InputStream>{ private ImageView ivPic; private String url; @Override protected void onProgressUpdate(Void... values) { super.onProgressUpdate(values); } @Override protected void onPostExecute(InputStream inputStream) { if (inputStream!=null){ BitmapFactory.Options options=new BitmapFactory.Options(); options.inSampleSize=2; options.inPreferredConfig= Bitmap.Config.ARGB_4444; Bitmap bitmap=BitmapFactory.decodeStream(inputStream,null,options); ivPic.setImageBitmap(bitmap); System.out.println("从网络中获取图片成功"); //保存在本地 localCacheUtils.setBitmapToLocal(context,url,inputStream); //保存在缓存 memoryCacheUtils.setBitmapToMemory(url,bitmap); } } @Override protected InputStream doInBackground(Object... params) { ivPic= (ImageView) params[0]; url= (String) params[1]; return downLoadBitmap(url); } } private InputStream downLoadBitmap(String url) { HttpURLConnection connection=null; try { connection=(HttpURLConnection)new URL(url).openConnection(); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); connection.setRequestMethod("GET"); int responseCode=connection.getResponseCode(); if (responseCode==200){ return connection.getInputStream(); } } catch (Exception e) { e.printStackTrace(); }finally { connection.disconnect(); } return null; }}
三级缓存之内存缓存MemoryCacheUtils,使用LruCache
public class MemoryCacheUtils { private LruCache<String,Bitmap> lruCache; public MemoryCacheUtils(){ //获取手机最大内存的1/8 long memory=Runtime.getRuntime().maxMemory()/8; lruCache=new LruCache<String, Bitmap>((int)memory){ @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } }; } /** * 从内存中读图片 * @param url * @return */ public Bitmap getBitmapFromMemory(String url) { Bitmap bitmap = lruCache.get(url); return bitmap; } public void setBitmapToMemory(String url, Bitmap bitmap) { lruCache.put(url,bitmap); }}
三级缓存之本地缓存LocalCacheUtils,使用DiskLruCache
public class LocalCacheUtils { DiskLruCache mDiskLruCache = null; private DiskLruCache getDiskLruCache(Context context){ try { File cacheDir = getDiskCacheDir(context, "bitmap"); if (!cacheDir.exists()) { cacheDir.mkdirs(); } mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024); } catch (IOException e) { e.printStackTrace(); } return mDiskLruCache; } public Bitmap getBitmapFromLocal(String url) { try { DiskLruCache.Snapshot snapShot = mDiskLruCache.get(getMD5String(url)); if (snapShot != null) { InputStream is = snapShot.getInputStream(0); Bitmap bitmap = BitmapFactory.decodeStream(is); return bitmap; } } catch (IOException e) { e.printStackTrace(); } return null; } public void setBitmapToLocal(Context context,String url, InputStream inputStream) { BufferedOutputStream out = null; BufferedInputStream in = null; try { DiskLruCache.Editor editor = getDiskLruCache(context).edit(getMD5String(url)); if (editor != null) { OutputStream outputStream = editor.newOutputStream(0); in = new BufferedInputStream(inputStream, 8 * 1024); out = new BufferedOutputStream(outputStream, 8 * 1024); int b; while ((b = in.read()) != -1) { out.write(b); } editor.commit(); } mDiskLruCache.flush(); } catch (IOException e) { e.printStackTrace(); } } public File getDiskCacheDir(Context context, String uniqueName) { String cachePath; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath + File.separator + uniqueName); } public int getAppVersion(Context context) { try { PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return info.versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return 1; } public String getMD5String(String key) { String cacheKey; try { final MessageDigest mDigest = MessageDigest.getInstance("MD5"); mDigest.update(key.getBytes()); cacheKey = bytesToHexString(mDigest.digest()); } catch (NoSuchAlgorithmException e) { cacheKey = String.valueOf(key.hashCode()); } return cacheKey; } private String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xFF & bytes[i]); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); }}