Android面试题(23)-图片的三级缓存工具类

时间:2021-06-21 14:15:32

上一篇博客已经把三级缓存原理大致都讲了,这篇博客就仅仅贴一下封装好的一个图片三级缓存工具类,代码内有注释,仅仅小记一下:

首先是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();    }}