Android自制图片的三级缓存(代码+讲解)

Android的图片三级缓存机制

首先
图片的三计划缓存的概念
泛指的是 -内存缓存 -本地缓存 -网络缓存

内存缓存的概念
应用程序在运行时 WindowMeanger会分配给 应用 相应的运行时内存
运行是内存的大小根据android版本有关系

本地缓存的概念
本地缓存是存储在硬件上的数据

网络缓存的概念
图片存储在网络上,需要下载

小结
这三种缓存的概念以上以及陈述了,既然我们要做一个服务于图片的缓存,那么
我们就要应用起来这三种缓存到 我们的这个 demo里面
要应用它 首先 我们做一下项目规划 这个缓存 每一个缓存都要是个单独的类
保持封装性 然后调用的时候要简单 一行代码就调用
那么我们 还要做一个 proxy
好 下面开始

内存设计代码


import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
/**
 * LruCache工具类
 * @author 浩
 *
 */
public class MemoryCacheUtils {

    private LruCache<String, Bitmap> lruCache;//集合

    public MemoryCacheUtils() {
        int maxSize = (int) Runtime.getRuntime().maxMemory();
        lruCache = new LruCache<String, Bitmap>(maxSize){

            @Override
            protected int sizeOf(String key, Bitmap value) {
                // TODO Auto-generated method stub
                return value.getRowBytes() * value.getHeight();
            }



        };
    }

    /**
     * 根据url从内存中得到缓存图片
     * @param url
     * @return
     */
    public Bitmap getBitmapFromUril(String url) {
        // TODO Auto-generated method stub
        return lruCache.get(url);
    }

    /**
     * 根据url,和bitmp在内存中保存一份bitmap
     * @param url
     * @param bitmap
     */
    public void putBitmap2Memory(String url, Bitmap bitmap) {
        //每个应用占多少内存:16MB
        lruCache.put(url, bitmap);

    }

}

本地缓存设计

mport android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.widget.ImageView;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class LocalCacheUtils {
    /**
     * 本地缓存工具类
     * 
     * @author 王浩
     *
     */

    private static final String ATGUIT_DIR = "/mnt/sdcard/beijingnews/";

    /**
     * 根据Bitmap保存图片到本地
     * 
     * @param url
     * @param bitmap
     */
    public void putBitmap2Local(String url, Bitmap bitmap) {
        // TODO Auto-generated method stub
        try {
            // String name = MD5Encoder.encode(url);
            // /mnt/sdcard/beijingnews/lskkskklllkk(md5加密)
            File file = new File(ATGUIT_DIR, url);
            // mnt/sdcard/beijingnews/创建
            File parentFile = file.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }

            // 图片就保存到sdcard了
            FileOutputStream stream = new FileOutputStream(file);

            bitmap.compress(CompressFormat.JPEG, 100, stream);

            stream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 根据uri取对应的图片
     * 
     * @param url
     * @return
     */
    public Bitmap getBitmapFromUrl(String url, ImageView imageView, int tag) {
        try {
            File file = new File(ATGUIT_DIR, url);
            if (file.isFile()) {
                Bitmap bitmap = null ;
                FileInputStream fis = new FileInputStream(file);
                fis.close();
                return bitmap;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

网络缓存设计


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 网络缓存图片的工具类
 *
 * @author 王浩
 */
public class NetCatchUtils {

    /**
     * 网络请求图片成功
     */
    public static final int SUCESS = 0;
    /**
     * 网络请求图片失败
     */
    public static final int FAIL = 1;
    private Handler handler;
    /**
     * 本地缓存工具类
     */
    private LocalCacheUtils localCacheUtils;
    /**
     * 内存缓存工具
     */
    private MemoryCacheUtils memoryCacheUtils;

    public NetCatchUtils(Handler handler, LocalCacheUtils localCacheUtils,
                         MemoryCacheUtils memoryCacheUtils) {
        // TODO Auto-generated constructor stub
        this.handler = handler;
        this.localCacheUtils = localCacheUtils;
        this.memoryCacheUtils = memoryCacheUtils;
    }

    /**
     * 根据图片路径,请求网络图片
     *
     * @param url
     * @param position
     * @return
     */
    public Bitmap getBitmapFromUrl(String url, int position, int tag,
                                   Activity ac, ImageView tv_image) {
        new Thread(new MyRunnable(url, position, tag, ac, tv_image)).start();

        return null;
    }

    class MyRunnable implements Runnable {

        private String url;
        private int position;
        private int tag;
        private Activity ac;
        private ImageView tv_image;

        public MyRunnable(String url, int position, int tag, Activity ac,
                          ImageView tv_image) {



            this.url = url;
            this.position = position;
            this.tag = tag;
            this.ac = ac;
            this.tv_image = tv_image;
        }


        /**
         * 处理大图片加载问题
         */
        @Override
        public void run() {
            HttpURLConnection con = null;
            try {

                  con = (HttpURLConnection) new
                        URL(url).openConnection();

                int code = con.getResponseCode();


                if (200 == code) {
                    InputStream is = con.getInputStream();

                    Options opts = new Options();

                    // 根据计算出的比例进行缩放
                    int scale = ImageUtils.getScare(url, ac);
                    opts.inSampleSize = scale;

                    Bitmap bm = BitmapFactory.decodeStream(is, null, opts);

                    // 将bm发生给主线程用于显示图片,更新UI
                    Message msg = Message.obtain();
                    msg.obj = bm;
                    msg.arg1 = tag;
                    msg.arg2 = position;



                    tv_image.post(new Action(bm, tv_image));
//                    if(handler!=null) {
//                        tv_image.post(new Action(bm, tv_image));
//                        //handler.sendMessage(msg);
//                    } else {
//                        Utils.log2("tv_image:" + bm + "————tv_image:" + tv_image);
//                        //tv_image.setImageBitmap(bm);
//
//
//                    }

                    // 保存一份在内存
                    memoryCacheUtils.putBitmap2Memory(url, bm);
                    // 保存一份在本地(Sdcard)
                    localCacheUtils.putBitmap2Local(url, bm);

                }
            } catch (Exception e) {
//                e.printStackTrace();
            }

        }

    }


    /**
     * 在主线程更新UI
     */
    class Action implements Runnable{

        private Bitmap  bit ;
        private ImageView img  ;

        public Action(Bitmap bit,ImageView img) {
            this.bit  = bit;
            this.img  = img;
        }


        @Override
        public void run() {

            img.setImageBitmap(bit);
        }
    }

}

代理者设计


/**
 * 三级缓存工具类
 * 
 * @author wanghao
 *
 */
public class ImageCacheProxy {

    public static final int LARGE_PHOTO = -11 ;
    /**
     * 一级本地缓存
     */
    LocalCacheUtils localCacheUtils;
    /**
     * 二级内存缓存
     */
    private MemoryCacheUtils memoryCacheUtils;
    /**
     * 三级网络获取图片
     */
    private NetCatchUtils netUtils ;
    /**
     * 初始化三级缓存
     * @param handler
     */
    public ImageCacheProxy() {
        localCacheUtils = new LocalCacheUtils();
        memoryCacheUtils = new MemoryCacheUtils();
        netUtils = new NetCatchUtils(null, localCacheUtils, memoryCacheUtils);
    }



        /**
         * @param tv_image 要把bit替换成image的image
         * @param url 请求图片的地址
         * @param position 给图片做的tag  方便 handler ,里面 去取
         * @param tag arg1的标记
         */
    public void imageLoader(ImageView tv_image, String url, int position, int tag ,Activity ac) {
        Bitmap bit;

        bit = localCacheUtils.getBitmapFromUrl(url,tv_image,tag);
        if (bit != null) {
            tv_image.setImageBitmap(bit);
            return;
        }
        bit = memoryCacheUtils.getBitmapFromUril(url);
        if (bit != null) {
            tv_image.setImageBitmap(bit);
            return;
        }
        netUtils.getBitmapFromUrl(url, position, tag ,ac,tv_image);
    }


}

这就OK了 调用 只需要一行代码loader下 就行了

附上我写的 demo project 地址

https://github.com/mywanghao/twentythreemodule/tree/master/imagecachedemo
这个是一个很多demo的一个集合里面 如果要运行 建议 donwload twentythreemodule这个主 porject

本篇博客结束
如果觉得对你有帮助

粉我把
关注更多我的blog.

技术交流群:

博客圈 493554215

这是一个热爱分享技术,拥有热烈学习氛围的群 ,
博主身为群内的一员感到骄傲
推荐还在路上的伙伴们

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值