我们在做安卓开发的时候难免会遇到图片加载的问题,但是加载的时候如果每次进入这个页面我们都加载图片的话这样会极大的消耗用户的流量,造成用户的体验不好,所以我们采用图片三级缓存来解决这一问题。
图片三级缓存分为内存缓存,硬盘缓存(SD卡缓存),网络缓存。我们在请求数据的时候首先是从内存中取出如果内存中没有缓存的话从硬盘中获取缓存如果硬盘中也没有缓存的话最后才从网络加载图片
一、内存缓存
首先我们要创建一个用于做内存缓存的MemorycacheUtils类
public class MemorycacheUtils { private final LruCache memorycache; public MemorycacheUtils(){ //获取可运行的最大内存 int maxMemory = (int) Runtime.getRuntime().maxMemory(); //分配给图片的内存(总内存的八分之一) int i = maxMemory / 8; //创建LruCache集合存储获取到的值 memorycache = new LruCache(i) { protected int sizeOf(String key,Bitmap value) { //利用Value返回长度 return value.getByteCount(); } }; } //设置添加的方法 public void saveBitmapToMemoryCahce(String url,Bitmap bitmap){ memorycache.put(url,bitmap); } //设置获取的方法 public Bitmap getBitmapFromMemoryCache(String url){ return memorycache.get(url); } }
二、硬盘缓存(SD卡缓存)
在定义一个用于做硬盘缓存的DiskcacheUtils类
public class DiskcacheUtils { //获取SD卡的绝对路径 String urlpath= Environment.getExternalStorageDirectory().getAbsolutePath() +"/Newsphoto"; //设置添加方法 public void saveBitmapToCache(String path , Bitmap bitmap) throws UnsupportedEncodingException { //用MD5Util对文件名加密 String encryption = MD5Util.getEncryption(path); File file = new File(urlpath, encryption); try { // bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file)); } catch (FileNotFoundException e) { e.printStackTrace(); } } //设置获取方法 public Bitmap getBitmapFromDiskcache(String url) throws UnsupportedEncodingException { //用MD5Util类对文件名加密 String encryption = MD5Util.getEncryption(url); File file=new File(urlpath,encryption); Bitmap bitmap=null; try { //获取BitmapFactory工厂 的字节输入流 bitmap= BitmapFactory.decodeStream(new FileInputStream(file)); } catch (FileNotFoundException e) { e.printStackTrace(); } return bitmap; } }
三、网络缓存
网络缓存的类NetWorkUtils
public class NetWorkUtils { private final MemorycacheUtils memorycacheUtils; private final DiskcacheUtils diskcacheUtils; //定义有参方法传入内存缓存类和SD卡缓存类 public NetWorkUtils(MemorycacheUtils memorycacheUtils, DiskcacheUtils diskcacheUtils) { this.memorycacheUtils =memorycacheUtils; this.diskcacheUtils=diskcacheUtils; } //网络获取图片 public void execute(String pathurl, ImageView imageView){ //定义实现图片加载的内部类 BitmapTask bitmapTask = new BitmapTask(); //内部类调用方法 传值 bitmapTask.execute(pathurl,imageView); } //内部类 class BitmapTask extends AsyncTask { private String pathurl; private ImageView imageView; @Override protected Bitmap doInBackground(Object... objects) { //获取图片路径 pathurl = (String) objects[0]; //获取图片控件 imageView = (ImageView) objects[1]; Bitmap bitmap = null; try { //加载图片的方法 bitmap = downloadbitmap(); } catch (IOException e) { e.printStackTrace(); } return bitmap; } //把图片设置给控件 @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); if (bitmap!=null){ imageView.setImageBitmap(bitmap); } //同时保存在内存 memorycacheUtils.saveBitmapToMemoryCahce(pathurl,bitmap); try { //保存在SD卡中 diskcacheUtils.saveBitmapToCache(pathurl,bitmap); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } //URL网络获取图片 private Bitmap downloadbitmap() throws IOException { URL url=new URL(pathurl); HttpURLConnection con= (HttpURLConnection) url.openConnection(); con.connect(); if (con.getResponseCode()==200){ InputStream inputStream = con.getInputStream(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds=true; options.inSampleSize=2; options.inJustDecodeBounds=false; Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options); return bitmap; } return null; } } }
我们虽然把相关操作的类都定义了出来但是我们如何使用呢?所以还需要定义一个使用它的类
四、定义BitmapUtils类调用
public class BitmapUtils { private MemorycacheUtils memorycacheUtils; private DiskcacheUtils diskcacheUtils; private NetWorkUtils netWorkUtils; //定义无参方法New出实体类 public BitmapUtils() { this.memorycacheUtils = new MemorycacheUtils(); this.diskcacheUtils = new DiskcacheUtils(); this.netWorkUtils = new NetWorkUtils(memorycacheUtils, diskcacheUtils); } //定义传值的方法 public void showBitmap(String pathurl, ImageView imageView) { //调用内存中获取图片的方法 Bitmap bitmapFromMemoryCache =memorycacheUtils.getBitmapFromMemoryCache(pathurl); if (bitmapFromMemoryCache!=null){ imageView.setImageBitmap(bitmapFromMemoryCache); } try { //调用SD卡中获取图片的方法 bitmapFromMemoryCache = diskcacheUtils.getBitmapFromDiskcache(pathurl); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //调用网络获取的方法 if (bitmapFromMemoryCache!=null){ imageView.setImageBitmap(bitmapFromMemoryCache); } netWorkUtils.execute(pathurl,imageView); } }