android图片的三级缓存

来源:互联网 发布:网络接入控制 编辑:程序博客网 时间:2024/05/22 15:31

一、图片的三级缓存
1. 内存
    1. 内存的引用
        1. 强引用
            特点:没有变量引用 ,就会被垃圾回收线程收到,直到程序崩溃,也不会回收
        2. 软引用
            特点:垃圾回收线程执行,不一定会回收,内存不足的时候,崩溃之前,清理软引用
        3. 弱引用
            特点:垃圾回收线程一跑,就被回收
        4. 虚引用
            特点:垃圾回收一跑也被清理,该应用获取的数据都为null

     2. 针对android系统
         1.  LruCache
               内存不足时,回收该容器中的数据
2. 本地(硬盘)
       文件:
              sdcard

              app(/data/data/包名/cache)

              sharedpreferences
3. 网络
        网络读取 

二、使用操作

    1. 先从内存取
    2. 再从本地文件中
    3. 从网络取

三、加载网络图片错位
1. 标记

四、代码
public class BitmapCacheUtils{    //动态获取jvm的内存    private int maxSize = (int) (Runtime.getRuntime().freeMemory() / 2);    //图片的缓存容器    private LruCache<String, Bitmap> memCache = new LruCache<String, Bitmap>(maxSize) {        @Override        protected int sizeOf(String key, Bitmap value) {            // TODO Auto-generated method stub            return value.getRowBytes() * value.getHeight();        }    };    //保留最后一次访问url的信息    private Map<ImageView,String> urlImageViewDatas = new HashMap<ImageView, String>();    private File cacheDir ;    private MainActivity mainActivity;    private ExecutorService    threadPool;    public BitmapCacheUtils(MainActivity mainActivity) {        this.mainActivity = mainActivity;        //获取当前app的cache目录        cacheDir = mainActivity.getCacheDir();        //线程池        threadPool = Executors.newFixedThreadPool(6);    }    public void display(ImageView iv, String ivUrl) {       <span style="color:#FF0000;"> // 1. 先从内存取</span>        Bitmap bitmap = memCache.get(ivUrl);        if (bitmap != null) {            System.out.println("从内存获取数据");            //缓存中有图片            iv.setImageBitmap(bitmap);            return;        }       <span style="color:#FF0000;"> // 2. 再从本地文件中, app(/data/data/包名/cache)</span>        bitmap = getCacheFile(ivUrl);        if (bitmap != null) {            System.out.println("从文件获取数据");            //本地文件中有图片            iv.setImageBitmap(bitmap);            return;        }       <span style="color:#FF0000;"> // 3. 从网络取</span>        urlImageViewDatas.put(iv, ivUrl);//保留最后一次访问的url        getBitmapFromNet(iv, ivUrl);    }    private void getBitmapFromNet(ImageView iv, String ivUrl) {        //new Thread(new DownLoadUrl(iv, ivUrl)).start();        //线程池        threadPool.submit(new DownLoadUrl(iv, ivUrl));    }    private class DownLoadUrl implements Runnable{        private String ivUrl;        private ImageView iv;        public DownLoadUrl(ImageView iv,String ivUrl){            this.iv = iv;            this.ivUrl = ivUrl;        }        @Override        public void run() {            //访问网络             try {                URL url = new URL(ivUrl);                HttpURLConnection con = (HttpURLConnection) url.openConnection();                con.setConnectTimeout(6000);//设置超时时间                con.setRequestMethod("GET");                int code = con.getResponseCode();                if (code == 200) {                    //请求成功                    InputStream inputStream = con.getInputStream();                    final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);                    //1.往内存中添加                    memCache.put(ivUrl, bitmap);                    //2.往本地文件中添加                    saveBitmapToCacheFile(bitmap,ivUrl);                    //3.显示数据                    mainActivity.runOnUiThread(new Runnable() {                        @Override                        public void run() {                            System.out.println("从网络获取数据");                            // 显示图片                            // 判断url是不是最新的                            //是最新的 自己的数据                            if (ivUrl.equals(urlImageViewDatas.get(iv))) {                                //自己的数据                                iv.setImageBitmap(bitmap);                            }                        }                    });                }            } catch (MalformedURLException e) {                // TODO Auto-generated catch block                e.printStackTrace();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    /**     * 保存bitmap到cache目录的文件中     * @param bitmap     * @param ivUrl     */    public void saveBitmapToCacheFile(Bitmap bitmap,String ivUrl) {        File file = new File(cacheDir,Md5Utils.md5(ivUrl));        try {            bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(file));        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    /**     * @param ivUrl     *     当做缓存图片的名字     * @return     */    public Bitmap getCacheFile(String ivUrl){        //把ivUrl转换MD5值,再把md5 做文件名        File file = new File(cacheDir,Md5Utils.md5(ivUrl));        if (file != null  && file.exists()) {            //文件存在            //把文件转换成bitmap            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());            //再往内存写            memCache.put(ivUrl, bitmap);            return bitmap;        } else {            //不存在            return null;        }    }}五、MD5工具类<pre name="code" class="java">public class Md5Utils {/** * @param path *    ?????·?? * @return *    ?????MD5? */public static String getFileMD5(String path){StringBuilder mess = new StringBuilder();try {FileInputStream fis = new FileInputStream(new File(path));//???MD5??????MessageDigest md = MessageDigest.getInstance("MD5");byte[] buffer = new byte[10240];int len = fis.read(buffer);while (len != -1) {md.update(buffer, 0, len);//??????len = fis.read(buffer);}byte[] digest = md.digest();for (byte b : digest){//???????????16??????  int d = b & 0xff;// 0x000000ffString hexString = Integer.toHexString(d);if (hexString.length() == 1) {//?????4λ?0hexString = "0" + hexString;}hexString = hexString.toUpperCase();mess.append(hexString);//????????????2λ??????????????????}} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return mess + "";}public static String md5(String str){StringBuilder mess = new StringBuilder();try {//???MD5??????MessageDigest md = MessageDigest.getInstance("MD5");byte[] bytes = str.getBytes();byte[] digest = md.digest(bytes);for (byte b : digest){//???????????16??????  int d = b & 0xff;// 0x000000ffString hexString = Integer.toHexString(d);if (hexString.length() == 1) {//?????4λ?0hexString = "0" + hexString;}mess.append(hexString);//????????????2λ??????????????????}} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();}return mess + "";}}





0 0
原创粉丝点击