博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
硅谷新闻9--图片三级缓存
阅读量:7196 次
发布时间:2019-06-29

本文共 10479 字,大约阅读时间需要 34 分钟。

1.三级缓存设计步骤:

* 从内存中取图片

* 从本地文件中取图片
     向内存中保持一份
* 请求网络图片,获取图片,显示到控件上
     向内存存一份
     向本地文件中存一份

1 package com.atguigu.beijingnews.utils; 2  3 import android.graphics.Bitmap; 4 import android.os.Handler; 5  6 public class BitmapCacheUtils { 7  8     /** 9      * 网络缓存工具类10      */11     private NetCacheUtils netCacheUtils;12 13     /**14      * 本地缓存工具类15      */16 17     private LocalCacheUtils localCacheUtils;18 19     /**20      内存缓存工具类21      */22     private MemoryCacheUtils memoryCacheUtils;23 24     public BitmapCacheUtils(Handler handler) {25         memoryCacheUtils = new MemoryCacheUtils();26         localCacheUtils = new LocalCacheUtils(memoryCacheUtils);27         netCacheUtils = new NetCacheUtils(handler,localCacheUtils,memoryCacheUtils);28 29     }30 31 32     /**33      * 三级缓存设计步骤:34      *   * 从内存中取图片35      *   * 从本地文件中取图片36      *        向内存中保持一份37      *   * 请求网络图片,获取图片,显示到控件上,Hanlder,postion38      *      * 向内存存一份39      *      * 向本地文件中存一份40      *41      * @param imageUrl42      * @param position43      * @return44      */45     public Bitmap getBitmap(String imageUrl, int position) {46         //1.从内存中取图片47         if (memoryCacheUtils != null) {48             Bitmap bitmap = memoryCacheUtils.getBitmapFromUrl(imageUrl);49             if (bitmap != null) {50                 LogUtil.e("内存加载图片成功=="+position);51                 return bitmap;52             }53         }54 55         //2.从本地文件中取图片56         if (localCacheUtils != null) {57             Bitmap bitmap = localCacheUtils.getBitmapFromUrl(imageUrl);58             if (bitmap != null) {59                 LogUtil.e("本地加载图片成功=="+position);60                 return bitmap;61             }62         }63 64         //3.请求网络图片65         netCacheUtils.getBitmapFomNet(imageUrl, position);66         return null;67     }68 }
BitmapCacheUtils

 

2.网络缓存

线程池类Executors的使用

public static ExecutorService newCachedThreadPool()

创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。

public static ExecutorService newFixedThreadPool(int nThreads)

创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。

1 package com.atguigu.beijingnews.utils; 2  3 import android.graphics.Bitmap; 4 import android.graphics.BitmapFactory; 5 import android.os.Handler; 6 import android.os.Message; 7  8 import java.io.IOException; 9 import java.io.InputStream;10 import java.net.HttpURLConnection;11 import java.net.URL;12 import java.util.concurrent.ExecutorService;13 import java.util.concurrent.Executors;14 15 public class NetCacheUtils {16 17     /**18      * 请求图片成功19      */20     public static final int SUCESS = 1;21     /**22      * 请求图片失败23      */24     public static final int FAIL = 2;25     private final Handler handler;26     /**27      * 本地缓存工具类28      */29     private final LocalCacheUtils localCacheUtils;30     /**31      * 内存缓存工具类32      */33     private final MemoryCacheUtils memoryCacheUtils;34     /**35      * 线程池类36      */37     private  ExecutorService service;38 39     public NetCacheUtils(Handler handler, LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) {40         this.handler = handler;41         service = Executors.newFixedThreadPool(10);42         this.localCacheUtils = localCacheUtils;43         this.memoryCacheUtils =memoryCacheUtils;44     }45 46     //联网请求得到图片47     public void getBitmapFomNet(String imageUrl, int position) {48 //        new Thread(new MyRunnable(imageUrl,position)).start();49         service.execute(new MyRunnable(imageUrl,position));50     }51 52     class MyRunnable implements  Runnable{53 54         private final String imageUrl;55         private final int position;56 57         public MyRunnable(String imageUrl, int position) {58             this.imageUrl = imageUrl;59             this.position = position;60         }61 62         @Override63         public void run() {64             //子线程65             //请求网络图片66             try {67                 URL urL = new URL(imageUrl);68                 HttpURLConnection connection = (HttpURLConnection) urL.openConnection();69                 connection.setRequestMethod("GET");//只能大写70                 connection.setConnectTimeout(4000);71                 connection.setReadTimeout(4000);72                 connection.connect();//可写可不写73                 int code = connection.getResponseCode();74                 if(code ==200){75                     InputStream is = connection.getInputStream();76                     Bitmap bitmap = BitmapFactory.decodeStream(is);77 78                     //显示到控件上,发消息吧Bitmap发出去和position79                     Message msg = Message.obtain();80                     msg.what = SUCESS;81                     msg.arg1 = position;82                     msg.obj = bitmap;83                     handler.sendMessage(msg);84 85                     //在内存中缓存一份86                     memoryCacheUtils.putBitmap(imageUrl,bitmap);87                     //在本地中缓存一份88                     localCacheUtils.putBitmap(imageUrl,bitmap);89                 }90             } catch (IOException e) {91                 e.printStackTrace();92                 Message msg = Message.obtain();93                 msg.what = FAIL;94                 msg.arg1 = position;95                 handler.sendMessage(msg);96             }97         }98     }99 }
NetCacheUtils

 

3.本地缓存

File file = new File(CACHE_DIR, fileName);  FileInputStream FileOutputStream 文件读写方式

演示把图片移除后,在查看

C:\Users\Administrator>adb shell
# cd /mnt/sdcard/atguigu_beijingnews
cd /mnt/sdcard/atguigu_beijingnews
# rm *
rm *

1 package com.atguigu.beijingnews.utils; 2  3 import android.graphics.Bitmap; 4 import android.graphics.BitmapFactory; 5 import android.os.Environment; 6  7 import java.io.File; 8 import java.io.FileInputStream; 9 import java.io.FileOutputStream;10 11 public class LocalCacheUtils {12     private final MemoryCacheUtils memoryCacheUtils;13 14     public LocalCacheUtils(MemoryCacheUtils memoryCacheUtils) {15         this.memoryCacheUtils = memoryCacheUtils;16     }17 18     /**19      * 根据Url获取图片20      * @param imageUrl21      * @return22      */23     public Bitmap getBitmapFromUrl(String imageUrl) {24         //判断sdcard是否挂载25         if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){26             //保存图片在/mnt/sdcard/beijingnews/http://192.168.21.165:8080/xsxxxx.png27             //保存图片在/mnt/sdcard/beijingnews/llkskljskljklsjklsllsl28             try {29                 String fileName = MD5Encoder.encode(imageUrl);//llkskljskljklsjklsllsl30 31                 ///mnt/sdcard/beijingnews/llkskljskljklsjklsllsl32                 File file = new File(Environment.getExternalStorageDirectory()+"/beijingnews",fileName);33 34 35 36 37                 if(file.exists()){38 39                     FileInputStream is = new FileInputStream(file);40                     Bitmap bitmap = BitmapFactory.decodeStream(is);41                     if(bitmap != null){42                         memoryCacheUtils.putBitmap(imageUrl,bitmap);43                         LogUtil.e("把从本地保持到内存中");44                     }45                     return  bitmap;46 47                 }48 49             } catch (Exception e) {50                 e.printStackTrace();51                 LogUtil.e("图片获取失败");52             }53         }54 55         return null;56     }57 58     /**59      * 根据Url保存图片60      * @param imageUrl url61      * @param bitmap 图片62      */63     public void putBitmap(String imageUrl, Bitmap bitmap) {64 65         //判断sdcard是否挂载66         if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){67             //保存图片在/mnt/sdcard/beijingnews/http://192.168.21.165:8080/xsxxxx.png68             //保存图片在/mnt/sdcard/beijingnews/llkskljskljklsjklsllsl69             try {70                 String fileName = MD5Encoder.encode(imageUrl);//llkskljskljklsjklsllsl71 72                 ///mnt/sdcard/beijingnews/llkskljskljklsjklsllsl73                 File file = new File(Environment.getExternalStorageDirectory()+"/beijingnews",fileName);74 75                 File parentFile =  file.getParentFile();//mnt/sdcard/beijingnews76                 if(!parentFile.exists()){77                     //创建目录78                     parentFile.mkdirs();79                 }80 81 82                 if(!file.exists()){83                     file.createNewFile();84                 }85                 //保存图片86                 bitmap.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(file));87 88             } catch (Exception e) {89                 e.printStackTrace();90                 LogUtil.e("图片本地缓存失败");91             }92         }93 94 95     }96 }
LocalCacheUtils

 

4.内存缓存

引用级别

我们经常会使用一种非常流行的内存缓存技术的实现,即软引用或弱引用 (SoftReference or WeakReference)。

但是现在已经不再推荐使用这种方式了,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象;

另外,Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,

这就有潜在的风险造成应用程序的内存溢出并崩溃。所以看到还有很多相关文章还在推荐用软引用或弱引用 (SoftReference or WeakReference),就有点out了

 

Android3.0后提出新的方式

LruCache 缓存的集合,把常用的数据,保留起来,把不常用的给回收。
Lru近期最少使用算法

1 package com.atguigu.beijingnews.utils; 2  3 import android.graphics.Bitmap; 4  5 import org.xutils.cache.LruCache; 6  7 /** 8  * 作用:Java之软引用&弱引用&虚引用 9  */10 public class MemoryCacheUtils {11 12     /**13      * 集合14      */15     private LruCache
lruCache;16 17 public MemoryCacheUtils(){18 //使用了系统分配给应用程序的八分之一内存来作为缓存大小19 int maxSize = (int) (Runtime.getRuntime().maxMemory()/1024/8);20 lruCache = new LruCache
(maxSize){21 @Override22 protected int sizeOf(String key, Bitmap value) {23 // return super.sizeOf(key, value);24 return (value.getRowBytes() * value.getHeight())/1024;25 }26 };27 }28 29 /**30 * 根据url从内存中获取图片31 * @param imageUrl32 * @return33 */34 public Bitmap getBitmapFromUrl(String imageUrl) {35 return lruCache.get(imageUrl);36 }37 38 /**39 * 根据url保存图片到lruCache集合中40 * @param imageUrl 图片路径41 * @param bitmap 图片42 */43 public void putBitmap(String imageUrl, Bitmap bitmap) {44 lruCache.put(imageUrl,bitmap);45 }46 }
MemoryCacheUtils

 

转载地址:http://sftkm.baihongyu.com/

你可能感兴趣的文章
TYVJ P3522 &&洛谷 P1135 奇怪的电梯 Label:bfs
查看>>
C# 会可能需要的扩展
查看>>
彻底卸载Oracle
查看>>
bzoj2434
查看>>
银联支付集成之 ---- 安卓
查看>>
递归函数打印斐波那契数列
查看>>
rabbitmq的简单介绍二
查看>>
go语言之指针
查看>>
浅谈Cocos2d-js ListView滑动防止误触
查看>>
当、你想给一个目标挂上一个事件时
查看>>
模板:树链剖分
查看>>
JQ和Js获取span标签的内容
查看>>
8. java操作mongodb——查询数据
查看>>
NHProfiler使用方法
查看>>
《C和指针》读书笔记 第3章-数据
查看>>
ul li排版 左右对齐
查看>>
Java并发编程:Callable、Future和FutureTask
查看>>
CentOS卸载Apache方法
查看>>
“此文件来自其他计算机,可能被阻止以帮助保护该计算机” 教你win7解除阻止程序运行怎么操作...
查看>>
20170710总结
查看>>