Android图片三级缓存开发
时间:2019-04-13
本文章向大家介绍Android图片三级缓存开发,主要包括Android图片三级缓存开发使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
因为目前工程无法使用第三方,只能搞一个三级缓存了三级缓存分为内存缓存,本地缓存,网络缓存;缓存的步骤依次是网络,内存,本地,然后取的顺序为内存,本地,网络。在加载图片时引用时尽量采用弱引用避免出现图片过多产生OOM.。
1、内存缓存,android为我们提供LruCache=其中维护着一个LinkedHashMap。LruCache可以用来存储各种类型的数据,我们设置它的大小,一般是系统最大存储空间的1/8.
public class MemoryCacheUtil { private LruCache<String, Bitmap> lruCache; public MemoryCacheUtil(){ int maxSize = (int) (Runtime.getRuntime().maxMemory()/8); // 一般获取当前应用的最大内存的1/8作为LruCache的容量 lruCache = new LruCache<String, Bitmap>(maxSize){ // 设置当前添加的图片的大小 @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes()*value.getHeight(); } }; } // 从内存缓存取图片 public Bitmap getBitmap(String url){ return lruCache.get(url); } // 在内存缓存存图片 public void putBitmap(String url,Bitmap bitmap){ lruCache.put(url, bitmap); } }
2、本地缓存根据url,获取本地文件,把url进行md5加密,作为文件名,保证文件的正确性.
MD5加密工具类
public class MD5Encoder { public static String encode(String string) throws Exception { byte[] hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8")); StringBuilder hex = new StringBuilder(hash.length * 2); for (byte b : hash) { if ((b & 0xFF) < 0x10) { hex.append("0"); } hex.append(Integer.toHexString(b & 0xFF)); } return hex.toString(); } }
本地缓存
public class LocalCacheUtil { private String CACHE_URl; private MemoryCacheUtil memoryCacheUtil; public LocalCacheUtil(MemoryCacheUtil memoryCacheUtil){ // 初始化本地存储的路径 CACHE_URl = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/test"; this.memoryCacheUtil = memoryCacheUtil; } // 从本地sdcard取图片 public Bitmap getBitmap(String url){ // 根据url,获取本地文件,把url进行md5加密,作为文件名 try { String fileName = MD5Encoder.encode(url); File file = new File(CACHE_URl, fileName); if(file.exists()){// 判断当前文件是否存在 // 把当前文件转换成Bitmap对象 Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); // 需往内存中存一份 memoryCacheUtil.putBitmap(url, bitmap); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; } // 往本地存图片的方法 public void saveBitmap(String url,Bitmap bitmap){ try { String fileName = MD5Encoder.encode(url); File file = new File(CACHE_URl, fileName); // 判断是否需要创建父目录 File parentFile = file.getParentFile(); if(!parentFile.exists()){ parentFile.mkdirs(); } // 把Bitmap对象保存到文件中 质量越高压缩速度越慢 OutputStream stream = new FileOutputStream(file); bitmap.compress(CompressFormat.PNG, 100, stream);//第一个参数可以设置图片格式,第二个图片压缩质量,第三个为图片输出流 } catch (Exception e) { e.printStackTrace(); } } }
3、网络缓存使用异步加载AsyncTask,使用其有二种原因:
1.doInBackground运行在子线程,做网络请求耗时操作,避免主线程堵塞;
2.onPreExecute和onPostExecute便于更新UI提高用户体验。
public class NetCacheUtil { private MemoryCacheUtil memoryCacheUtil; private LocalCacheUtil localCacheUtil; private ListView lv_image_list; public NetCacheUtil(MemoryCacheUtil memoryCacheUtil,LocalCacheUtil localCacheUtil){ this.memoryCacheUtil = memoryCacheUtil; this.localCacheUtil = localCacheUtil; } public void display(ImageView imageView ,String url, ListView lv_image_list){ this.lv_image_list = lv_image_list; new MyAsyncTask(imageView).execute(new Object[]{url,imageView}); } class MyAsyncTask extends AsyncTask<Object, Void, Bitmap>{ private ImageView imageView; private int position; public MyAsyncTask(ImageView imageView2) { position = (Integer) imageView2.getTag(); } // 运行在主线程,做准备操作,在doInBackground之前,可以放置加载条提高用户体验 @Override protected void onPreExecute() { super.onPreExecute(); } // 运行在子线程,做耗时操作 @Override protected Bitmap doInBackground(Object... params) { // 获取url,下载图片 String url = (String) params[0]; // 获取ImageView imageView = (ImageView) params[1]; try { // 下载图片 HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.connect();// 连接网络 // 获取响应码 int resCode = conn.getResponseCode(); if(resCode==200){// 访问成功 // 把服务器返回的输入流转换成Bitmap对象 Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream()); // 保存到本地和内存 memoryCacheUtil.putBitmap(url, bitmap); localCacheUtil.saveBitmap(url, bitmap); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; } // 运行在主线程,更新界面,在doInBackground之后 @Override protected void onPostExecute(Bitmap result) { // 判断线程开始时,那个位置是否还在Listview中 ImageView view = (ImageView) lv_image_list.findViewWithTag(position); if(view!=null){ view.setImageBitmap(result); } super.onPostExecute(result); } } }
4、封装三级缓存形成ImageUtil,因内存缓存中取速度较快,所以先从内存缓存中取,取不到->本地缓存中取,取不到->网络缓存中取。
public class ImageUtils { private MemoryCacheUtil memoryCacheUtil; private LocalCacheUtil localCacheUtil; private NetCacheUtil netCacheUtil; public ImageUtils(){ memoryCacheUtil = new MemoryCacheUtil(); localCacheUtil = new LocalCacheUtil(memoryCacheUtil); netCacheUtil = new NetCacheUtil(memoryCacheUtil,localCacheUtil); } public void display(ImageView imageView, String url, ListView lv_photo_list) { Bitmap bitmap = null; /** * 因内存缓存中取速度较快 * 内存缓存中取,取不到->本地缓存中取,取不到->网络缓存中取 */ bitmap = memoryCacheUtil.getBitmap(url);//从内存缓存取图片 if(bitmap!=null){ imageView.setImageBitmap(bitmap); return; } bitmap = localCacheUtil.getBitmap(url);//从本地缓存取图片 if(bitmap!=null){ imageView.setImageBitmap(bitmap); return; } // 开启线程访问网络,下载图片,并且展示 netCacheUtil.display(imageView, url,lv_photo_list); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- silverlight图片局部放大效果
- 局域网与互联网环境下MTU的快速确定方法
- 【4】通过简化的正则表达式处理字符串
- silverlight中的socket编程注意事项
- socket中的byte消息格式设计
- 在silverlight中利用socket发送图片或文件
- 多线程中的ManualResetEvent
- 进程与线程
- ASP.NET TreeView相关问题
- 温故而知新:WinForm/Silverlight多线程编程中如何更新UI控件的值
- ASP.Net Web Page深入探讨
- 用Design+Blend轻松制作环形文字
- 对asp.net响应事件的试验
- 为服务器控件加入客户端事件处理的几种方法
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- (四十一)golang--goroutine
- (四十二)golang--协程之间通信的方式
- (四十三)golang--管道
- 绕过磊科路由器登录密码
- JeeSite | 数据权限应用
- 数据防泄漏 | 禁止PrintScreen键
- LeetCode | 实现strStr()
- LeetCode | 机器人能否返回原点
- LeetCode | 2 的幂
- JeeSite | Excel 导入导出
- 贪心法--哈夫曼编码
- 基于maven+ssm的增删改查之使用mybatis逆向工程生成相关文件
- Arrays 的二分查找
- (四十四)golang--协程(goroutine)和管道(channel)相结合实例
- 基于maven+ssm的增删改查之测试相关ssm环境是否成功