第一个csdn博客-图片三级缓存

来源:互联网 发布:c语言 p 编辑:程序博客网 时间:2024/05/16 00:53

首先,我是一个小菜鸟,刚学了到一点东西,虽然很小的一点东西,但我觉得应该记下来,帮助自己也希望帮到他人···
我对三级缓存的理解是,图片首先会在内存中加载,如果内存没有,则请求本地磁盘,有的话会加载到内存中一份,如果没有则请求网络,网络是费时费流量,所以会最后请求,磁盘和内存,内存加载更快,所以首先从内存中加载,所以加载顺序是内存- >磁盘- > 网络!!请求完网络,会在本地磁盘中保存一份,然后内存保存一份
1.创建一个BitmapCacheUtils类:
public class BitmapCacheUtils {

/** * 网络缓存工具类 */private NetCacheUtils netCacheUtils;/** * 本地缓存工具类 */private LocalCacheUtils localCacheUtils;/** * 内存缓存工具类 */private MemoryCacheUtils memoryCacheUtils;public BitmapCacheUtils(Handler handler) {//首先是内存    memoryCacheUtils=new MemoryCacheUtils();    //本地    localCacheUtils=new LocalCacheUtils(memoryCacheUtils);    //网络    netCacheUtils=new NetCacheUtils(handler,localCacheUtils,memoryCacheUtils);}/** * 三级缓存设计步骤 * 从内存中取图片,如果没有,则从本地加载 * 从本地文件中取图片 * 有的话向内存中保存一份,没有则请求网络 * 请求网络图片,获取图片,显示在控件上,Handler,position * 然后向内存中村一份 * 向本地文件存一份 * @param imageUrl * @param position * @return */public Bitmap getBitmap(String imageUrl, int position) {    //1.从内存中获取    if (memoryCacheUtils!=null){        Bitmap bitmap =memoryCacheUtils.getBitmapFromUrl(imageUrl);        if (bitmap!=null){            LogUtil.e("内存加载图片成功=="+position);            return bitmap;        }    }    //2.从本地中取图片    if (localCacheUtils!=null){        Bitmap bitmap =localCacheUtils.getBitmapFromUrl(imageUrl);        if (bitmap!=null){            LogUtil.e("本地加载图片成功=="+position);            return bitmap;        }    }    //3.从网络获取    netCacheUtils.getBitmapFromNet(imageUrl,position);    return null;}

}

2.创建三个类,
//网络缓存
public class NetCacheUtils {

/** * 请求图片成功 */public static final int SUCCESS =1;/** * 请求图片失败 */public static final int FAILURE = 2;private final Handler handler;/** * 本地缓存工具类 */private final LocalCacheUtils localCacheUtils;/** * 内存缓存工具类 */private final MemoryCacheUtils memoryCacheUtils;private ExecutorService service;public NetCacheUtils(Handler handler, LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) {    this.handler=handler;    this.service=Executors.newFixedThreadPool(10);//创建一个固定大小的线程池,返回一个线程池服务类    this.localCacheUtils=localCacheUtils;    this.memoryCacheUtils=memoryCacheUtils;}public void getBitmapFromNet(String imageUrl, int position) {

// new Thread(new MyRunnable(imageUrl,position)).start();
service.execute(new MyRunnable(imageUrl,position));
}

private class MyRunnable implements Runnable {    private final String imageUrl;    private final int position;    public MyRunnable(String imageUrl, int position) {        this.imageUrl=imageUrl;        this.position=position;    }    @Override    public void run() {        //子线程        //请求网络图片        try {            URL url=new URL(imageUrl);            HttpURLConnection connection= (HttpURLConnection) url.openConnection();            connection.setRequestMethod("GET");//只能大写            connection.setConnectTimeout(5000);            connection.setReadTimeout(4000);            connection.connect();//可写可不写            int code=connection.getResponseCode();            if (code==200){                LogUtil.e("请求成功");                InputStream is=connection.getInputStream();//获取一个输入流                Bitmap bitmap=BitmapFactory.decodeStream(is);//把输入流转成一个Bitmap对象                //显示在控件上,发消息把Bitmap发出去和position                Message msg=Message.obtain();//从队列中取一个空的消息                msg.what=SUCCESS;//请求图片成功                msg.arg1=position;                msg.obj=bitmap;                handler.sendMessage(msg);                //然后在内村中缓存一份                memoryCacheUtils.putBitmap(imageUrl,bitmap);                //然后在本地缓存一份                localCacheUtils.putBitmap(imageUrl,bitmap);            }else {                LogUtil.e("请求异常,请及时处理");            }        } catch (IOException e) {            e.printStackTrace();            Message msg=Message.obtain();            msg.what=FAILURE;            msg.arg1=position;            handler.sendMessage(msg);        }    }}

}

public class LocalCacheUtils {
private final MemoryCacheUtils memoryCacheUtils;

public LocalCacheUtils(MemoryCacheUtils memoryCacheUtils) {    this.memoryCacheUtils=memoryCacheUtils;}/** * 根据url获取图片 * @param imageUrl * @return */public Bitmap getBitmapFromUrl(String imageUrl) {    //判断sd卡是否挂载    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {        //保存图片在/mnt/sdcard/News        try {            String fileName = MD5Encoder.encode(imageUrl);//fnlkajdfjasfjasdf            File file=new File(Environment.getExternalStorageDirectory()+"/News",fileName);            if (file.exists()){                FileInputStream is=new FileInputStream(file);                Bitmap bitmap=BitmapFactory.decodeStream(is);                if (bitmap!=null){                    memoryCacheUtils.putBitmap(imageUrl,bitmap);                    LogUtil.e("把图片从本地保存到内存中");                }                return bitmap;            }        } catch (Exception e) {            e.printStackTrace();            LogUtil.e("图片获取失败");        }    }    return null;}/** * 根据url保存图片 * @param imageUrl url * @param bitmap 图片 */public void putBitmap(String imageUrl, Bitmap bitmap) {    //判断sd卡是否挂载    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {        //保存图片在/mnt/sdcard/News        try {            String fileName = MD5Encoder.encode(imageUrl);//fnlkajdfjasfjasdf            File file=new File(Environment.getExternalStorageDirectory()+"/News",fileName);            //本地没有这个目录要先进行创建            File parentFile =  file.getParentFile();//mnt/sdcard/News            if(!parentFile.exists()){                //创建目录                parentFile.mkdirs();            }            if (!file.exists()){                file.createNewFile();            }            //保存图片            bitmap.compress(Bitmap.CompressFormat.PNG,100, new FileOutputStream(file));        } catch (Exception e) {            e.printStackTrace();            LogUtil.e("图片本地缓存失败");        }    }}

}

public class MemoryCacheUtils {

//集合,装图片的private LruCache<String,Bitmap> lruCache;public MemoryCacheUtils() {    int maxSize= (int) (Runtime.getRuntime().maxMemory()/8);//如果这里写一个1024;    lruCache=new LruCache<String,Bitmap>(maxSize){        @Override        protected int sizeOf(String key, Bitmap value) {            return value.getRowBytes()*value.getHeight();//这里也要写一个1024;        }    };}/** * 根据url从内存中获取图片 * @param imageUrl * @return */public Bitmap getBitmapFromUrl(String imageUrl) {    return lruCache.get(imageUrl);}/** * 根据url保存图片到lruCache集合中 * @param imageUrl 图片路径 * @param bitmap 图片 */public void putBitmap(String imageUrl, Bitmap bitmap) {    lruCache.put(imageUrl,bitmap);}

}
//实例化图片缓存工具类,这是在要插入的activity中,或者fragment中

private BitmapCacheUtils bitmapCacheUtils;//创建一个handler,需要发送到BitmapCacheUtils类中//然后网络请求成功之后,将图片位置等的信息传过来private Handler handler=new Handler(){    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        switch (msg.what){            case NetCacheUtils.SUCCESS://图片请求成功                int position=msg.arg1;                Bitmap bitmap= (Bitmap) msg.obj;                LogUtil.e("联网请求图片成功=="+position);                if (lv_photos_menu.isShown()) {                    ImageView imageView = (ImageView) lv_photos_menu.findViewWithTag(position);                    if (imageView != null && bitmap != null) {                        imageView.setImageBitmap(bitmap);                    }                }else if (gv_photos_menu.isShown()){                    ImageView imageView = (ImageView) gv_photos_menu.findViewWithTag(position);                    if (imageView != null && bitmap != null) {                        imageView.setImageBitmap(bitmap);                    }                }                break;            case NetCacheUtils.FAILURE://图片请求失败                position=msg.arg1;                LogUtil.e("联网请求图片成功=="+position);                break;        }    }};public InteractMenuDetailPager(Context context, NewsBean.DataEntity dataEntity) {    super(context);    this.dataEntity=dataEntity;    //实例化三级缓存类    bitmapCacheUtils=new BitmapCacheUtils(handler);}

//从内存或者本地获取
Bitmap bitmap=bitmapCacheUtils.getBitmap(imageUrl,position);
//往适配器中插入数据
holder.iv_photos_default_menu.setImageBitmap(bitmap);
}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 学生欠了2万块怎么办 玉米去完库存量cool怎么办 幸福蓝海电子券过期怎么办 幸福蓝海国际影城会员怎么办 幸福蓝海会员卡过期了怎么办 电机线圈处于平衡位置怎么办 混联电路求电功率最小怎么办 电脑超出工作频率范围怎么办 手机红外线感应器坏了怎么办 我的世界左右慢怎么办 发电机自动启停装置故障怎么办 如果自动启停没关发动机涉水怎么办 偏激的人不分手怎么办 被极端的人纠缠怎么办 对固执偏激的人怎么办 车子右前轮偏磨怎么办? 轮胎边缘磨黑了怎么办 36周胎儿绕颈一周怎么办 孕中期胎儿偏小怎么办 怀孕34周偏小2周怎么办 胎盘低怎么办6个月了 怀孕四个月胎盘低怎么办 怀孕五个月胎盘低怎么办 怀孕3个月胎盘低怎么办 怀孕三个月了胎盘低怎么办 新房交房开发商拿不出证件怎么办? 新干式变压器未送电进水怎么办 三相380转单相220怎么办 外国人一直找你出去怎么办 美团众包跑腿单物品太重怎么办 美团退款成功后 物品怎么办 win10电脑没有网络图标怎么办 电脑开机桌面什么都没有怎么办 xp桌面什么都没有了怎么办 手机下滑通知栏不见了怎么办 跑800米赶上月经怎么办 强迫症吃药没效怎么办 复读生档案丢了怎么办 大学退学重新高考学籍怎么办 玻尿酸鼻子宽了怎么办 被昆山市圆通快递公司骗怎么办