zoukankan      html  css  js  c++  java
  • 图片的三级缓存基础

    1.图片缓存优先级:Bitmap优于手机本地的图片文件优于服务器端的图片文件

    一级缓存:内存缓存,缓存的是bitmap对象(这些对象在内存如何存储呢?一般而言有两种方式:List和Map,List根据下标来得到对象,Map根据Key得到对象,实际图片存储都是用Map)。

    二级缓存:本地(SD卡)缓存,缓存的是图片文件,/storage/sdcard/Android/data/packageName/files/图片文件名(xxx.jpg)

    三级缓存:远程服务器缓存,缓存的是图片文件,远程服务器上的应用中

    2.如何使用三级缓存?-----如何根据图片的URL动态显示图片?

    String imagePath = http://192.168.10.165:8080//L05_Web/images/f10.jpg和ImageView对象

    1)。根据Url从一级缓存中取对应的bitmap对象

            如果有,显示(结束)

           如果没有,进入2

    2)。从二级缓存中查找:得到文件名,并在sd卡的缓存目录下加载对应的图片得到Bitmap对象

            如果有:显示,缓存到一级缓存中(结束) 

            如果没有,进入3

    3)。显示代表提示正在加载的图片,启动分线程联网请求得到Bitmap对象

            如果没有:显示提示错误的图片(结束)

            如果有:

                         显示

                         缓存到一级缓存

                         缓存到二级缓存

      1 /**  
      2     String iamgePath = http://192.168.10.165:8080//L05_Web/images/f10.jpg和ImageView对象  
      3     1). 根据url从一级缓存中取对应的bitmap对象  
      4         如果有, 显示(结束)  
      5         如果没有, 进入2)  
      6     2). 从二级缓存中查找: 得到文件名并在sd卡的缓存目录下加载对应的图片得到Bitmap对象  
      7         如果有: 显示, 缓存到一级缓存中(结束)  
      8         如果没有, 进入3)  
      9     3). 显示代表提示正在加载的图片, 启动分线程联网请求得到Bitmap对象  
     10             如果没有: 显示提示错误的图片(结束)  
     11             如果有:   
     12                 显示  
     13                 缓存到一级缓存  
     14                 缓存到二级缓存  
     15  */  
     16 public class ImageLoader {  
     17       
     18     private Context context;  
     19     private int loadingImageRes;  
     20     private int errorImageRes;  
     21   
     22     public ImageLoader(Context context, int loadingImageRes, int errorImageRes) {  
     23         super();  
     24         this.context = context;  
     25         this.loadingImageRes = loadingImageRes;  
     26         this.errorImageRes = errorImageRes;  
     27     }  
     28   
     29     //用于缓存bitmap的容器对象  
     30     private Map<String, Bitmap> cacheMap = new HashMap<String, Bitmap>();  
     31       
     32     /**  
     33      * 加载图片并显示  
     34      * @param imagePath  
     35      * @param imageView  
     36      */  
     37     public void loadImage(String imagePath, ImageView imageView) {  
     38           
     39         //将需要显示的图片url保存到视图上  
     40         imageView.setTag(imagePath);  
     41           
     42         /*  
     43          1). 根据url从一级缓存中取对应的bitmap对象  
     44             如果有, 显示(结束)  
     45             如果没有, 进入2)  
     46          */  
     47         Bitmap bitmap = getFromFirstCache(imagePath);  
     48         if(bitmap!=null) {  
     49             imageView.setImageBitmap(bitmap);  
     50             return;  
     51         }  
     52         /*  
     53         2). 从二级缓存中查找: 得到文件名并在sd卡的缓存目录下加载对应的图片得到Bitmap对象  
     54                 如果有: 显示, 缓存到一级缓存中(结束)  
     55                 如果没有, 进入3)  
     56               
     57             /storage/sdcard/Android/data/packageName/files/图片文件名(xxx.jpg)  
     58          */  
     59         bitmap = getFromSecondCache(imagePath);  
     60         if(bitmap!=null) {  
     61             imageView.setImageBitmap(bitmap);  
     62             cacheMap.put(imagePath, bitmap);  
     63             return;  
     64         }  
     65           
     66         /*  
     67          3). 显示代表提示正在加载的图片, 启动分线程联网请求得到Bitmap对象  
     68             如果没有: 显示提示错误的图片(结束)  
     69             如果有:   
     70                 缓存到一级缓存(分线程)  
     71                 缓存到二级缓存(分线程)  
     72                 显示(主线程)  
     73                   
     74          */  
     75           
     76         loadBitmapFromThirdCache(imagePath, imageView);  
     77     }  
     78   
     79     /**  
     80      * 根据图片url从三级缓存中取对应的bitmap对象并显示  
     81      * @param imagePath  
     82      * @param imageView  
     83      * AsyncTask  
     84      * loadBitmapFromThirdCache("../b.jpg", imageView)  
     85      * loadBitmapFromThirdCache("../f.jpg", imageView)--->imageView.setTag("../f.jpg")  
     86      */  
     87     private void loadBitmapFromThirdCache(final String imagePath, final ImageView imageView) {  
     88         new AsyncTask<Void, Void, Bitmap>() {  
     89             protected void onPreExecute() {  
     90                 imageView.setImageResource(loadingImageRes);  
     91             }  
     92               
     93             //联网请求得到bitmap对象  
     94             @Override  
     95             protected Bitmap doInBackground(Void... params) {  
     96                 //在分线程执行, 可能需要等待一定时间才会执行  
     97                 //在等待的过程中imageView中的tag值就有可能改变了  
     98                 //如果改变了, 就不应该再去加载图片(此图片此时不需要显示)  
     99                   
    100                 Bitmap bitmap = null;  
    101                 try {  
    102                       
    103                     //在准备请求服务器图片之前, 判断是否需要加载  
    104                     String newImagePath = (String) imageView.getTag();  
    105                     if(newImagePath!=imagePath) {//视图已经被复用了  
    106                         return null;  
    107                     }  
    108                       
    109                     //得到连接  
    110                     URL url = new URL(imagePath);  
    111                     HttpURLConnection connection = (HttpURLConnection) url.openConnection();  
    112                     //设置  
    113                     connection.setConnectTimeout(5000);  
    114                     connection.setReadTimeout(5000);  
    115                     //连接  
    116                     connection.connect();  
    117                     //发请求读取返回的数据并封装为bitmap  
    118                     int responseCode = connection.getResponseCode();  
    119                     if(responseCode==200) {  
    120                         InputStream is = connection.getInputStream();//图片文件流  
    121                         //将is封装为bitmap  
    122                         bitmap = BitmapFactory.decodeStream(is);  
    123                         is.close();  
    124                           
    125                         if(bitmap!=null) {  
    126                             //缓存到一级缓存(分线程)  
    127                             cacheMap.put(imagePath, bitmap);  
    128                             //缓存到二级缓存(分线程)  
    129                             // /storage/sdcard/Android/data/packageName/files/  
    130                             String filesPath = context.getExternalFilesDir(null).getAbsolutePath();  
    131                             // http://192.168.10.165:8080//L05_Web/images/f10.jpg  
    132                             String fileName = imagePath.substring(imagePath.lastIndexOf("/")+1);//  f10.jpg  
    133                             String filePath = filesPath+"/"+fileName;  
    134                             bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(filePath));  
    135                         }  
    136                     }  
    137                     connection.disconnect();  
    138                 } catch (Exception e) {  
    139                     e.printStackTrace();  
    140                 }  
    141                   
    142                   
    143                 return bitmap;  
    144             }  
    145               
    146             protected void onPostExecute(Bitmap bitmap) {//从联网请求图片到得到图片对象需要一定的时间, 视图可能被复用了,不需要显示  
    147                 //在主线程准备显示图片之前, 需要判断是否需要显示  
    148                 String newImagePath = (String) imageView.getTag();  
    149                 if(newImagePath!=imagePath) {//视图已经被复用了  
    150                     return;  
    151                 }  
    152                           
    153                 //如果没有: 显示提示错误的图片(结束)  
    154                 if(bitmap==null) {  
    155                     imageView.setImageResource(errorImageRes);  
    156                 } else {//如果有, 显示  
    157                     imageView.setImageBitmap(bitmap);  
    158                 }  
    159             }  
    160         }.execute();  
    161     }  
    162   
    163     /**  
    164      * 根据图片url从二级缓存中取对应的bitmap对象  
    165      * @param imagePath  
    166      * @return  
    167      */  
    168     private Bitmap getFromSecondCache(String imagePath) {  
    169           
    170         // /storage/sdcard/Android/data/packageName/files/  
    171         String filesPath = context.getExternalFilesDir(null).getAbsolutePath();  
    172         // http://192.168.10.165:8080//L05_Web/images/f10.jpg  
    173         String fileName = imagePath.substring(imagePath.lastIndexOf("/")+1);//  f10.jpg  
    174         String filePath = filesPath+"/"+fileName;  
    175           
    176         return BitmapFactory.decodeFile(filePath);  
    177     }  
    178   
    179     /**  
    180      * 根据图片url从一级缓存中取对应的bitmap对象  
    181      * @param imagePath  
    182      * @return  
    183      */  
    184     private Bitmap getFromFirstCache(String imagePath) {  
    185         return cacheMap.get(imagePath);  
    186     }  
    187 }

    运行效果:

    但是,图片一直在变换,并不固定。

    视频学习地址:http://www.gulixueyuan.com/course/112/task/1732/show

    图片三级缓存进阶:https://blog.csdn.net/lovoo/article/details/51456515

  • 相关阅读:
    分布式搜索引擎Elasticsearch的查询与过滤
    剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作
    分布式缓存 cachecloud
    npm是什么NPM的全称是Node Package Manager
    Grafana监控可视化环境搭建
    github ssl验证跳过
    Linux分区扩容
    手把手教你把Vim改装成一个IDE编程环境(图文)
    根据条件批量删除document
    奇智网络聊天机器人
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/6058580.html
Copyright © 2011-2022 走看看