Android自制图片的三级缓存(代码+讲解)
2016-03-17 23:07
826 查看
Android的图片三级缓存机制
首先图片的三计划缓存的概念
泛指的是 -内存缓存 -本地缓存 -网络缓存
内存缓存的概念:
应用程序在运行时 WindowMeanger会分配给 应用 相应的运行时内存
运行是内存的大小根据android版本有关系
本地缓存的概念
本地缓存是存储在硬件上的数据
网络缓存的概念
图片存储在网络上,需要下载
小结
这三种缓存的概念以上以及陈述了,既然我们要做一个服务于图片的缓存,那么
我们就要应用起来这三种缓存到 我们的这个 demo里面
要应用它 首先 我们做一下项目规划 这个缓存 每一个缓存都要是个单独的类
保持封装性 然后调用的时候要简单 一行代码就调用
那么我们 还要做一个 proxy
好 下面开始
内存设计代码
import android.graphics.Bitmap; import android.support.v4.util.LruCache; /** * LruCache工具类 * @author 浩 * */ public class MemoryCacheUtils { private LruCache<String, Bitmap> lruCache;//集合 public MemoryCacheUtils() { int maxSize = (int) Runtime.getRuntime().maxMemory(); lruCache = new LruCache<String, Bitmap>(maxSize){ @Override protected int sizeOf(String key, Bitmap value) { // TODO Auto-generated method stub return value.getRowBytes() * value.getHeight(); } }; } /** * 根据url从内存中得到缓存图片 * @param url * @return */ public Bitmap getBitmapFromUril(String url) { // TODO Auto-generated method stub return lruCache.get(url); } /** * 根据url,和bitmp在内存中保存一份bitmap * @param url * @param bitmap */ public void putBitmap2Memory(String url, Bitmap bitmap) { //每个应用占多少内存:16MB lruCache.put(url, bitmap); } }
本地缓存设计
mport android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.widget.ImageView; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class LocalCacheUtils { /** * 本地缓存工具类 * * @author 王浩 * */ private static final String ATGUIT_DIR = "/mnt/sdcard/beijingnews/"; /** * 根据Bitmap保存图片到本地 * * @param url * @param bitmap */ public void putBitmap2Local(String url, Bitmap bitmap) { // TODO Auto-generated method stub try { // String name = MD5Encoder.encode(url); // /mnt/sdcard/beijingnews/lskkskklllkk(md5加密) File file = new File(ATGUIT_DIR, url); // mnt/sdcard/beijingnews/创建 File parentFile = file.getParentFile(); if (!parentFile.exists()) { parentFile.mkdirs(); } // 图片就保存到sdcard了 FileOutputStream stream = new FileOutputStream(file); bitmap.compress(CompressFormat.JPEG, 100, stream); stream.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 根据uri取对应的图片 * * @param url * @return */ public Bitmap getBitmapFromUrl(String url, ImageView imageView, int tag) { try { File file = new File(ATGUIT_DIR, url); if (file.isFile()) { Bitmap bitmap = null ; FileInputStream fis = new FileInputStream(file); fis.close(); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; } }
网络缓存设计
import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.os.Handler; import android.os.Message; import android.widget.ImageView; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; /** * 网络缓存图片的工具类 * * @author 王浩 */ public class NetCatchUtils { /** * 网络请求图片成功 */ public static final int SUCESS = 0; /** * 网络请求图片失败 */ public static final int FAIL = 1; private Handler handler; /** * 本地缓存工具类 */ private LocalCacheUtils localCacheUtils; /** * 内存缓存工具 */ private MemoryCacheUtils memoryCacheUtils; public NetCatchUtils(Handler handler, LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) { // TODO Auto-generated constructor stub this.handler = handler; this.localCacheUtils = localCacheUtils; this.memoryCacheUtils = memoryCacheUtils; } /** * 根据图片路径,请求网络图片 * * @param url * @param position * @return */ public Bitmap getBitmapFromUrl(String url, int position, int tag, Activity ac, ImageView tv_image) { new Thread(new MyRunnable(url, position, tag, ac, tv_image)).start(); return null; } class MyRunnable implements Runnable { private String url; private int position; private int tag; private Activity ac; private ImageView tv_image; public MyRunnable(String url, int position, int tag, Activity ac, ImageView tv_image) { this.url = url; this.position = position; this.tag = tag; this.ac = ac; this.tv_image = tv_image; } /** * 处理大图片加载问题 */ @Override public void run() { HttpURLConnection con = null; try { con = (HttpURLConnection) new URL(url).openConnection(); int code = con.getResponseCode(); if (200 == code) { InputStream is = con.getInputStream(); Options opts = new Options(); // 根据计算出的比例进行缩放 int scale = ImageUtils.getScare(url, ac); opts.inSampleSize = scale; Bitmap bm = BitmapFactory.decodeStream(is, null, opts); // 将bm发生给主线程用于显示图片,更新UI Message msg = Message.obtain(); msg.obj = bm; msg.arg1 = tag; msg.arg2 = position; tv_image.post(new Action(bm, tv_image)); // if(handler!=null) { // tv_image.post(new Action(bm, tv_image)); // //handler.sendMessage(msg); // } else { // Utils.log2("tv_image:" + bm + "————tv_image:" + tv_image); // //tv_image.setImageBitmap(bm); // // // } // 保存一份在内存 memoryCacheUtils.putBitmap2Memory(url, bm); // 保存一份在本地(Sdcard) localCacheUtils.putBitmap2Local(url, bm); } } catch (Exception e) { // e.printStackTrace(); } } } /** * 在主线程更新UI */ class Action implements Runnable{ private Bitmap bit ; private ImageView img ; public Action(Bitmap bit,ImageView img) { this.bit = bit; this.img = img; } @Override public void run() { img.setImageBitmap(bit); } } }
代理者设计
/** * 三级缓存工具类 * * @author wanghao * */ public class ImageCacheProxy { public static final int LARGE_PHOTO = -11 ; /** * 一级本地缓存 */ LocalCacheUtils localCacheUtils; /** * 二级内存缓存 */ private MemoryCacheUtils memoryCacheUtils; /** * 三级网络获取图片 */ private NetCatchUtils netUtils ; /** * 初始化三级缓存 * @param handler */ public ImageCacheProxy() { localCacheUtils = new LocalCacheUtils(); memoryCacheUtils = new MemoryCacheUtils(); netUtils = new NetCatchUtils(null, localCacheUtils, memoryCacheUtils); } /** * @param tv_image 要把bit替换成image的image * @param url 请求图片的地址 * @param position 给图片做的tag 方便 handler ,里面 去取 * @param tag arg1的标记 */ public void imageLoader(ImageView tv_image, String url, int position, int tag ,Activity ac) { Bitmap bit; bit = localCacheUtils.getBitmapFromUrl(url,tv_image,tag); if (bit != null) { tv_image.setImageBitmap(bit); return; } bit = memoryCacheUtils.getBitmapFromUril(url); if (bit != null) { tv_image.setImageBitmap(bit); return; } netUtils.getBitmapFromUrl(url, position, tag ,ac,tv_image); } }
这就OK了 调用 只需要一行代码loader下 就行了
附上我写的 demo project 地址
https://github.com/mywanghao/twentythreemodule/tree/master/imagecachedemo这个是一个很多demo的一个集合里面 如果要运行 建议 donwload twentythreemodule这个主 porject
本篇博客结束
如果觉得对你有帮助
粉我把
关注更多我的blog.
技术交流群:
博客圈 493554215
这是一个热爱分享技术,拥有热烈学习氛围的群 ,
博主身为群内的一员感到骄傲
推荐还在路上的伙伴们
相关文章推荐
- Android图片缩放
- 一个三年Android开发的总结-git基础知识与协作开发
- Android:RecyclerView嵌套CardView应用
- 在Eclipse中关联Android Private Libraries中文件的源代码
- android TextView实现滚动显示效果
- 源码解析Android onmeasure()的量算过程
- Android入门教程 Fragment使用教程【实例讲解】
- Android Studio中提示:Project SDK is not defined
- #Android学习#Animation简单使用
- Android开发最佳实践
- Android Studio adb无法启动解决方案
- Android Service的绑定简介
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Toolbar完整封装
- 初入android之CheckBox
- Android 进程常驻(5)----开机广播的简单守护以及总结
- Android 内核 - 03 创建应用窗口 和 子窗口
- Throwable:Invalid stub element type in index
- Android pm命令详解
- Android 内核 - 02 Context