实现三级缓存
2015-10-17 22:22
597 查看
博客转移到个人站点:
http://www.wangchengmeng.club/2018/02/04/%E5%AE%9E%E7%8E%B0%E4%B8%89%E7%BA%A7%E7%BC%93%E5%AD%98/
欢迎来吐槽
2.优点
3.实现一个三级缓存图片的工具类
http://www.wangchengmeng.club/2018/02/04/%E5%AE%9E%E7%8E%B0%E4%B8%89%E7%BA%A7%E7%BC%93%E5%AD%98/
欢迎来吐槽
三级缓存
1.思想:1.从网络上获取数据,效率比较低,速度较慢,而且需要联网 2.为了更高的提高读取已经从网络上获取过的数据,并且在没联网的情况下也可以浏览,在第一次从网络上获取数据的时候将数据存储到缓存文件中 3.为了提高读取效率,直接从内存中读取是最快的,可以将获取的数据保存到内存中(LruCache),在内存足够的情况下,系统直接从内存中读取数据,效率是比较高的,当然,当内存不足的时候,系统会回收你在内存中保存在数据,这个时候你就需要从缓存文件中读取,如果缓存文件没有的情况下,你再从网络上获取。
2.优点
1.对于读取你已经从网络上读取过的数据,使用三级缓存,可以大大提高读取数据的效率, 2.在没有联网的情况下你仍可以读取你保存的数据 3.不必每次都需要从网络上去获取数据,只是第一次访问的时候需要访问网络,节省了流量
3.实现一个三级缓存图片的工具类
1.定义一个工具类 BitmapCacheUtils并实现其构造方法 public class BitmapCacheUtils { private HomeActivity mContext; private LruCache<String, Bitmap> lruCache; private ExecutorService threadPool; HashMap<ImageView,String> hm = new HashMap<ImageView,String>(); public BitmapCacheUtils(HomeActivity context) { this.mContext = context; int maxSize = (int) (Runtime.getRuntime().freeMemory() / 2); //运行的可用内存的一半 //线程池 threadPool = Executors.newFixedThreadPool(3); //1级缓存的容器 软引用 //参数是你允许的最大缓存,你存储的数据不可以超过这个值, lruCache = new LruCache<String, Bitmap>(maxSize){ @Override protected int sizeOf(String key, Bitmap value) { //动态计算每张图片的大小 return value.getRowBytes() * value.getHeight(); } }; } 2.定义一个方法(根据传入的url给ImageView添加图片) public void display(ImageView image, String url) { // 首先从内存获取数据 内存有数据了 就不必去本地或者网络中获取了,提高效率 Bitmap bitmap = lruCache.get(url); if(bitmap != null){ image.setImageBitmap(bitmap); return; } // 从本地缓存文件中获取数据 Bitmap bitmap2 = getBitmapFromCache(url); ---》3. if(bitmap2 != null){ //本地有数据了,就直接本地获取,不必去网络中获取了 image.setImageBitmap(bitmap2); return ; } //获取之前先将url存储在hashMap中 hm.put(image, url); // 从网络获取数据 getDataFromNet(image, url); ---》4. } 3.从本地读取图片的时候,如果读取有数据,也将其保存到内存中 private Bitmap getBitmapFromCache(String url){ //http://www.baidu.com/mm.png url类似这钟,/在文件中是会影响到路径的读取,所以截取最后一个/后面的字符作为文件名 File file = new File(mContext.getCacheDir(),url.substring(url.lastIndexOf("/") + 1)); Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); if(bitmap != null){ //如果本地有文件 在内存中保存一份 lruCache.put(url, bitmap); } return bitmap; } 4.从网络中读取数据(耗时操作放在子线程中执行) private void getDataFromNet(ImageView image, String url) { //线程池提交任务 使用线程池 提高效率 threadPool.submit(new Task(image,url)); } //线程执行的任务类 private class Task implements Runnable{ public ImageView img; public String url; public Task(ImageView img ,String url){ this.img = img; this.url = url; } @Override public void run() { getFromNet(img, url); ---》5. } } 5.联网获取图片 protected void getFromNet(final ImageView image, final String url) { try { URL cacheUrl = new URL(url); HttpURLConnection connection = (HttpURLConnection) cacheUrl .openConnection(); connection.setConnectTimeout(5000); connection.setRequestMethod("GET"); connection.connect(); int code = connection.getResponseCode(); if (code == 200) { // 请求成功 InputStream is = connection.getInputStream(); final Bitmap bitmap = BitmapFactory.decodeStream(is); // 往内存写入数据 lruCache.put(url, bitmap); ---》6. // 往本地写数据 write2Local(bitmap, url); ----》7. //子线程中不可以更新UI mContext.runOnUiThread(new Runnable() { @Override public void run() { //在设置图片的时候,判断绑定的url是否是新的 if(hm.get(image).equals(url)){ //是新的url那就可以进行绑定了 image.setImageBitmap(bitmap); } } }); } } catch (Exception e) { e.printStackTrace(); } } 6.往内存中写入数据 // 往内存写入数据 lruCache.put(url, bitmap); 主要是 LruCache这个类 实例化: int maxSize = (int) (Runtime.getRuntime().freeMemory() / 2); //运行的可用内存的一半 //1级缓存的容器 软引用 //参数是你允许的最大缓存,你存储的数据不可以超过这个值, lruCache = new LruCache<String, Bitmap>(maxSize){ @Override protected int sizeOf(String key, Bitmap value) { //动态计算每张图片的大小 return value.getRowBytes() * value.getHeight(); } }; 7.往本地写入数据 protected void write2Local(Bitmap bitmap, String url) { // 缓存文件 File cacheDir = mContext.getCacheDir(); File file = new File(cacheDir, url.substring(url.lastIndexOf("/") + 1)); try { // 写入图片 bitmap.compress(CompressFormat.PNG, 100, new FileOutputStream(file)); } catch (FileNotFoundException e) { e.printStackTrace(); } }
相关文章推荐
- GetChar缓存机制深入剖析
- 浅谈Ajax的缓存机制
- 英特尔Nehalem微架构三级缓存原理学习
- 浏览器缓存机制
- Hibernate缓存机制详解
- Http协议详解
- UNIX环境高级编程———第三章习题
- android Application类的详细介绍
- 浏览器 HTTP 协议缓存机制详解及Http协议预处理工具类
- 安卓客户端缓存机制
- Hibernate 的缓存机制
- java对象本地缓存机制的实现
- Android 缓存机制
- Android性能优化典范(三)
- Android数据持久化存储-Files对象
- hibernate的session机制初探
- LRU缓存介绍与实现 (Java)
- HIBERNATE的缓存机制
- Java基本类型包装类的缓存机制的自我理解
- hibernate的缓存问题