• 图片的三级缓存机制


    图片的三级缓存机制

    1. 简介

    现在android应用中不可避免的要使用图片,有些图片是可以变化的,需要每次启动时从网络拉取,这种场景在有广告位的应用以及纯图片应用(比如百度美拍)中比较多。

    现在有一个问题:假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量。在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很 耗流量的应用,其用户数量级肯定要受到影响。当然,我想,向百度美拍这样的应用,必然也有其内部的图片缓存策略。总之,图片缓存是很重要而且是必须的。

    2.图片缓存的原理

    实现图片缓存也不难,需要有相应的cache策略。这里我采用 内存(memory)-本地(local)-网络(Internet) 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且也把它划到缓存的层次结 构中。当根据url向网络拉取图片的时候,先从内存中找,如果内存中没有,再从本地缓存文件中查找,如果缓存文件中也没有,再从网络上通过http请求拉取图 片。在键值对(key-value)中,这个图片缓存的key是图片url的hash值,value就是bitmap。所以,按照这个逻辑,只要一个 url被下载过,其图片就被缓存起来了。

    3.图片缓存的比较

    ## 三级缓存 ##

    - 内存缓存, 优先加载, 速度最快
    - 本地缓存, 次优先加载, 速度快
    - 网络缓存, 不优先加载, 速度慢,浪费流量

    网络缓存 NetCacheUtils

      1 /**
      2  * 
      3  * 从网络下载图片
      4  * @author admin
      5  *
      6  */
      7 public class NetCacheUtils {
      8     private LocalCacheUtils mlocalcacheutils;
      9     private MemoryCacheUtils mmemorycacheutils;
     10 
     11     public NetCacheUtils(LocalCacheUtils localcacheutils, MemoryCacheUtils memorycacheutils) {
     12         mlocalcacheutils=localcacheutils;
     13         mmemorycacheutils=memorycacheutils;
     14     }
     15 
     16     public void getBitmapFromNet(ImageView iv_photo, String url) {
     17         // TODO Auto-generated method stub
     18         BitmapTask bitmaptask=new BitmapTask();
     19         bitmaptask.execute(iv_photo,url);//开启AsyncTask,参数在doInBackground获取
     20     }
     21     /*AsyncTask  异步任务即做一些简单的异步处理  ;是handle与线程池的封装
     22      * 第一个泛型:参数类型泛型
     23      * 第二个泛型:更新进度泛型
     24      * 第三个泛型:onProgressUpdate的返回结果的泛型
     25      * 
     26      */
     27     
     28     class BitmapTask extends AsyncTask<Object, Void, Bitmap>{
     29 
     30         private ImageView pic;
     31         private String murl;
     32         /**
     33          * 后台耗时方法在此执行,子线程
     34          */
     35         @Override
     36         protected Bitmap doInBackground(Object... params) {
     37             pic = (ImageView) params[0];
     38             murl = (String) params[1];
     39             
     40             pic.setTag(murl);//将图片与url绑定
     41             return downloadBitmap(murl);
     42         }
     43         /**
     44          * 更新进度,主线程
     45          */
     46         @Override
     47         protected void onProgressUpdate(Void... values) {
     48             // TODO Auto-generated method stub
     49             super.onProgressUpdate(values);
     50         }
     51         /**
     52          * 后台耗时方法结束之后,在此执行,主线程
     53          */
     54         @Override
     55         protected void onPostExecute(Bitmap result) {
     56             if(result!=null){
     57                 
     58                 String tag = (String) pic.getTag();
     59                 if(tag.equals(murl)){
     60                     pic.setImageBitmap(result);
     61                 }
     62                 
     63             }
     64             mlocalcacheutils.setBitmapTolocal(murl, result);
     65             mmemorycacheutils.setBitmapTomemory(murl, result);
     66             System.out.println("从网络上加载图片啦");
     67             
     68         }
     69     }
     70 
     71     /**
     72      * 
     73      * 下载图片
     74      * @return 
     75      */
     76     private Bitmap downloadBitmap(String url){
     77         HttpURLConnection conn=null;
     78         try {
     79             conn=(HttpURLConnection) new URL(url)
     80             .openConnection();
     81             
     82             conn.setConnectTimeout(5000);
     83             conn.setReadTimeout(5000);
     84             conn.setRequestMethod("GET");
     85             conn.connect();
     86             
     87             int responseCode = conn.getResponseCode();//响应码
     88             
     89             if(responseCode==200){//表示成功连接
     90                 InputStream inputStream = conn.getInputStream();
     91                 Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
     92                 return bitmap;
     93             }
     94             
     95         } catch (IOException e) {
     96             
     97             e.printStackTrace();
     98         }
     99         finally{
    100             conn.disconnect();
    101         }
    102         return null;
    103         
    104     }
    105 }

    本地缓存 LocalCacheUtils

     1 public class LocalCacheUtils {
     2     private static final String CACHE_PATH=Environment.getExternalStorageDirectory()
     3             .getAbsolutePath()+"/zhbj_cache_52";
     4 /**
     5  * 
     6  * 从本地读图片
     7  * @param url
     8  */
     9     public Bitmap getBitmapFromlocal(String url){
    10         try {
    11             String filename = MD5Encoder.encode(url);
    12             
    13             File file=new File(CACHE_PATH, filename);//通过父文件夹与自己的文件名称来创建一个文件
    14             
    15             if(file.exists()){
    16                 Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
    17                 return bitmap;
    18             }
    19             
    20         } catch (Exception e) {
    21             // TODO Auto-generated catch block
    22             e.printStackTrace();
    23         }
    24         return null;
    25         
    26     }
    27     
    28 /**
    29  * 
    30  * 将图片写到本地
    31  * @param url
    32  * @param bitmap
    33  */
    34     public void setBitmapTolocal(String url,Bitmap bitmap){
    35         try {
    36             String filename = MD5Encoder.encode(url);
    37             File file=new File(filename);
    38             File parentFile = file.getParentFile();
    39             if(!parentFile.exists()){//如果文件夾不存在,則创建
    40                 file.mkdirs();
    41             }
    42             //将图片保存到本地
    43             bitmap.compress(CompressFormat.JPEG, 100, 
    44                     new FileOutputStream(file));
    45                 
    46     
    47         } catch (Exception e) {
    48             // TODO Auto-generated catch block
    49             e.printStackTrace();
    50         }
    51         
    52     }
    53     
    54 }

    内存缓存 MemoryCacheUtils

     1 /**
     2  * 
     3  * 内存缓存
     4  * @author admin
     5  *
     6  */
     7 public class MemoryCacheUtils {
     8  
     9     private HashMap<String, Bitmap> hashlist=new HashMap<String, Bitmap>();
    10     /**
    11      * 
    12      * 从内存中读
    13      * @param url
    14      * @return
    15      */
    16     public  Bitmap getBitmapFrommemory(String url){
    17         Bitmap bitmap = hashlist.get(url);
    18         return bitmap;
    19     }
    20     
    21 
    22     /**
    23      * 
    24      * 写入内存
    25      * @param url
    26      * @param bitmap
    27      */
    28     public  void setBitmapTomemory(String url,Bitmap bitmap){
    29         hashlist.put(url, bitmap);
    30     }
    31 }

    MyBitmapUtils 调用

     1 /**
     2  * 
     3  * 
     4  * 自定义图片加载工具
     5  * @author admin
     6  *
     7  */
     8 public class MyBitMaputils {
     9     NetCacheUtils netcache;
    10     LocalCacheUtils localcacheutils;
    11     MemoryCacheUtils memorycacheutils;
    12     public MyBitMaputils(){
    13         memorycacheutils=new MemoryCacheUtils();
    14         localcacheutils=new LocalCacheUtils();
    15         netcache=new NetCacheUtils(localcacheutils,memorycacheutils);
    16         
    17     }
    18     Bitmap bitmap =null;
    19     public void display(ImageView iv_photo, String url) {
    20         iv_photo.setImageResource(R.drawable.news_pic_default);//默认图片,防止图片的复用
    21         //内存缓存
    22         bitmap= memorycacheutils.getBitmapFrommemory(url);
    23         if(bitmap!=null){
    24             iv_photo.setImageBitmap(bitmap);
    25             System.out.println("从内存中读取图片");
    26             return;
    27         }
    28         //本地缓存
    29         bitmap = localcacheutils.getBitmapFromlocal(url);
    30         if(bitmap!=null){
    31             iv_photo.setImageBitmap(bitmap);
    32             memorycacheutils.setBitmapTomemory(url, bitmap);
    33             System.out.println("从本地读取图片");
    34             return;//从本地读取就不需要从网络读取了
    35         }
    36         
    37         //网络缓存(第一次)
    38         netcache.getBitmapFromNet(iv_photo,url);
    39     }
    40 
    41     
    42 }
  • 相关阅读:
    Maven学习笔记
    [学习笔记] 网络流
    [Contest on 2021.11.3] 女子口阿
    [杂题合集] 25 岁小伙突然没了心跳,他的习惯很多年轻人都有!
    CSP 2021 提高组游记
    [题目小结] 可持久化数据结构
    [学习笔记] 无向图和有向图的连通分量
    [Contest on 2021.10.17] HustOJ 就是个 **
    [Contest on 2021.10.15] 细思极恐
    妖怪寺外,灯火通明
  • 原文地址:https://www.cnblogs.com/wangying222/p/5270048.html
Copyright © 2020-2023  润新知