图片的三级缓存——学习笔记
来源:互联网 发布:国内域名不备案 编辑:程序博客网 时间:2024/06/14 05:43
三级缓存的好处是:可以尽量避免内存溢出,提高程序执行效率,省流量,提供用户体验
- 内存缓存: 最快
- 本地缓存: 其次
- 网络缓存: 速度最慢
- 三级缓存设计步骤:
* 从内存中取图片
* 从本地文件中取图片
向内存中保持一份
* 请求网络图片,获取图片,显示到控件上
* 向内存存一份
* 向本地文件中存一份
首先是内存缓存MemoryCacheUtils:
public class MemoryCacheUtils { //集合 private LruCache<String, Bitmap> lruCache; public MemoryCacheUtils(){ //使用系统分配给应用最大内存的八分之一作为缓存大小 int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8 / 1024); lruCache = new LruCache<String, Bitmap>(maxSize){ @Override protected int sizeOf(String key, Bitmap value) {// return super.sizeOf(key, value); return (value.getRowBytes() * value.getByteCount()) / 1024; } }; } //根据Url从内存中获取图片 public Bitmap getBitmapFromUrl(String imageUrl) { return lruCache.get(imageUrl); } //根据Url保存图片到lruCache集合中去 public void putBitmap(String imageUrl, Bitmap bitmap) { lruCache.put(imageUrl, bitmap); }}
然后是本地缓存LocalCacheUtils:
public class LocalCacheUtils { private final MemoryCacheUtils memoryCacheUtils; public LocalCacheUtils(MemoryCacheUtils memoryCacheUtils) { this.memoryCacheUtils = memoryCacheUtils; } /** * 根据Url获取图片 * @param imageUrl * @return */ public Bitmap getBitmapFromUrl(String imageUrl) { //判断sdcard是否挂载 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //保存图片在/mnt/sdcard/beijingnews/http://192.168.21.165:8080/xsxxxx.png //保存图片在/mnt/sdcard/beijingnews/llkskljskljklsjklsllsl try { String fileName = MD5Encoder.encode(imageUrl);//llkskljskljklsjklsllsl ///mnt/sdcard/beijingnews/llkskljskljklsjklsllsl File file = new File(Environment.getExternalStorageDirectory()+"/beijingnews",fileName); if(file.exists()){ FileInputStream is = new FileInputStream(file); Bitmap bitmap = BitmapFactory.decodeStream(is); if(bitmap != null){ memoryCacheUtils.putBitmap(imageUrl,bitmap); LogUtils.e("把从本地保持到内存中"); } return bitmap; } } catch (Exception e) { e.printStackTrace(); LogUtils.e("图片获取失败"); } } return null; } /** * 根据Url保存图片 * @param imageUrl url * @param bitmap 图片 */ public void putBitmap(String imageUrl, Bitmap bitmap) { //判断sdcard是否挂载 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //保存图片在/mnt/sdcard/beijingnews/http://192.168.21.165:8080/xsxxxx.png //保存图片在/mnt/sdcard/beijingnews/llkskljskljklsjklsllsl try { String fileName = MD5Encoder.encode(imageUrl);//llkskljskljklsjklsllsl ///mnt/sdcard/beijingnews/llkskljskljklsjklsllsl File file = new File(Environment.getExternalStorageDirectory()+"/beijingnews",fileName); File parentFile = file.getParentFile();//mnt/sdcard/beijingnews if(!parentFile.exists()){ //创建目录 parentFile.mkdirs(); } if(!file.exists()){ file.createNewFile(); } //保存图片 bitmap.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(file)); } catch (Exception e) { e.printStackTrace(); LogUtils.e("图片本地缓存失败"); } } }}
最后是网络缓存NetCacheUtils :
public class NetCacheUtils { //请求图片成功 public static final int SUCESS = 1; //请求图片失败 public static final int FAIL = 2; private final Handler handler; private final LocalCacheUtils localCacheUtils; //本地缓存工具类 private final MemoryCacheUtils memoryCacheUtils;//内存缓存工具类 private ExecutorService service; //线程池类 public NetCacheUtils(Handler handler, LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) { this.handler = handler; service = Executors.newFixedThreadPool(10);//创建固定线程池,容量为10 this.localCacheUtils = localCacheUtils; this.memoryCacheUtils = memoryCacheUtils; } //联网请求得到图片 public void getBitmapFromNet(String imageUrl, int position) {// new Thread(new MyRunnable(imageUrl, position)).start(); service.execute(new MyRunnable(imageUrl, position)); } class MyRunnable implements Runnable{ private final String imageUrl; private final int position; public MyRunnable(String imageUrl, int position) { this.imageUrl = imageUrl; this.position = position; } @Override public void run() { //子线程 //请求网络图片 try { URL url = new URL(imageUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); //只能大写 connection.setConnectTimeout(4000); connection.setReadTimeout(4000); connection.connect(); //可写可不写 int code = connection.getResponseCode(); if (code == 200){ InputStream is = connection.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(is); //把输入流转换成Bitmap //显示到控件上,把Bitmap和position发出去 Message msg = Message.obtain(); msg.what = SUCESS; msg.arg1 = position; msg.obj = bitmap; handler.sendMessage(msg); //在内存中缓存一份 memoryCacheUtils.putBitmap(imageUrl, bitmap); //在本地中缓存一份 localCacheUtils.putBitmap(imageUrl, bitmap); } } catch (IOException e) { e.printStackTrace(); Message msg = Message.obtain(); msg.what = FAIL; msg.arg1 = position; handler.sendMessage(msg); } } }}
然后将三者集合到一个类中BitmapCacheUtils:
public class BitmapCacheUtils { private NetCacheUtils netCacheUtils;//网络缓存工具类 private LocalCacheUtils localCacheUtils;//本地缓存工具类 private MemoryCacheUtils memoryCacheUtils;//内存缓存工具类 public BitmapCacheUtils(Handler handler){ memoryCacheUtils = new MemoryCacheUtils(); localCacheUtils = new LocalCacheUtils(memoryCacheUtils); netCacheUtils = new NetCacheUtils(handler, localCacheUtils, memoryCacheUtils); } /*三级缓存设计步骤: * 从内存中取图片 * 从本地文件中取图片 向内存中保持一份 * 请求网络图片,获取图片,显示到控件上,Handler,position * 向内存存一份 * 向本地文件中存一份*/ public Bitmap getBitmap(String imageUrl, int position) { //1.从内存选取图片 if (memoryCacheUtils != null){ Bitmap bitmap = memoryCacheUtils.getBitmapFromUrl(imageUrl); if (bitmap != null){ LogUtils.e("内存加载图片成功——" + position); return bitmap; } } //2.从本地选取图片 if (localCacheUtils != null){ Bitmap bitmap = localCacheUtils.getBitmapFromUrl(imageUrl); if (bitmap != null){ LogUtils.e("本地加载图片成功——" + position); return bitmap; } } //3.从网络选取图片 netCacheUtils.getBitmapFromNet(imageUrl, position); return null; }}
最后,将文本缓存到SD卡中的方法:
//缓存文本数据 public static void putString(Context context, String key, String value) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //保存图片在/mnt/sdcard/beijingnews/http://192.168.0.103:8080/XSXXXX/png //保存图片在/mnt/sdcard/beijingnews/hkjhsdhakdhasd(加密!!!) try { String fileName = MD5Encoder.encode(key);//llkskljskljklsjklsllsl ///mnt/sdcard/beijingnews/llkskljskljklsjklsllsl File file = new File(Environment.getExternalStorageDirectory()+"/beijingnews/files",fileName); File parentFile = file.getParentFile();//mnt/sdcard/beijingnews/files if(!parentFile.exists()){ //创建目录 parentFile.mkdirs(); } if(!file.exists()){ file.createNewFile(); } //保存文本数据 FileOutputStream fileOutputStream = new FileOutputStream(file); fileOutputStream.write(value.getBytes()); fileOutputStream.close(); } catch (Exception e) { e.printStackTrace(); LogUtils.e("文本本地缓存失败"); } } else { SharedPreferences sp = context.getSharedPreferences("atguitu", Context.MODE_PRIVATE); sp.edit().putString(key, value).commit(); } } //缓存的文本信息 public static String getString(Context context, String key) { String result = ""; if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ try { String fileName = MD5Encoder.encode(key);//llkskljskljklsjklsllsl ///mnt/sdcard/beijingnews/llkskljskljklsjklsllsl File file = new File(Environment.getExternalStorageDirectory()+"/beijingnews/files",fileName); if(file.exists()){ FileInputStream is = new FileInputStream(file); ByteArrayOutputStream stream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) != -1){ stream.write(buffer, 0, length); } is.close(); stream.close(); result = stream.toString(); return result; } } catch (Exception e) { e.printStackTrace(); LogUtils.e("图片获取失败"); } } else { SharedPreferences sp = context.getSharedPreferences("atguitu", Context.MODE_PRIVATE); return sp.getString(key, ""); //这里用""空字符串,而不是null,不然会蹦 } return result; }
阅读全文
0 0
- 图片的三级缓存——学习笔记
- 某宅的Android学习笔记(二)——图片三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级 缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- 图片的三级缓存
- python的str()和repr()函数比较
- 邓志康原创Test
- angualrJs对数据库数据处理的增删改查
- spring mvc配置 + dbcp数据源+jdbcTemplate
- FreeRTOS常用API
- 图片的三级缓存——学习笔记
- 有人对他说:如果连 Python 都学不会,你就不要学编程了
- HTTP请求过程(http是一种无状态协议,即不建立持久的连接)
- 数据库安全的5个基本实践
- angular指令和自定义指令
- Java编程思想——复用类
- Android-使用Theme来解决启动app是出现的空白屏
- 帧动画通用更新代码
- 求解ax===b(mod m)的特解和[0,m)的所有解