栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

详解Android 图片的三级缓存及图片压缩

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

详解Android 图片的三级缓存及图片压缩

为什么需要图片缓存

Android默认给每个应用只分配16M的内存,所以如果加载过多的图片,为了防止内存溢出,应该将图片缓存起来。图片的三级缓存分别是:

  • 内存缓存
  • 本地缓存
  • 网络缓存

其中,内存缓存应优先加载,它速度最快;本地缓存次优先加载,它速度也快;网络缓存不应该优先加载,它走网络,速度慢且耗流量。

三级缓存的具体实现

网络缓存

  • 根据图片的url去加载图片
  • 在本地和内存中缓存

  

 public class NetCacheUtils {

    private LocalCacheUtils mLocalCacheUtils;
    private MemoryCacheUtils mMemoryCacheUtils;

    public NetCacheUtils(LocalCacheUtils localCacheUtils,
 MemoryCacheUtils memoryCacheUtils) {
      mLocalCacheUtils = localCacheUtils;
      mMemoryCacheUtils = memoryCacheUtils;
    }

    
    public void getBitmapFromNet(ImageView ivPic, String url) {
      new BitmapTask().execute(ivPic, url);// 启动AsyncTask,
     // 参数会在doInbackground中获取
    }

    
    class BitmapTask extends AsyncTask {

      private ImageView ivPic;
      private String url;

      
      @Override
      protected Bitmap doInBackground(Object... params) {
 ivPic = (ImageView) params[0];
 url = (String) params[1];

 ivPic.setTag(url);// 将url和imageview绑定

 return downloadBitmap(url);
      }

      
      @Override
      protected void onProgressUpdate(Void... values) {
 super.onProgressUpdate(values);
      }

      
      @Override
      protected void onPostExecute(Bitmap result) {
 if (result != null) {
   String bindUrl = (String) ivPic.getTag();

   if (url.equals(bindUrl)) {// 确保图片设定给了正确的imageview
     ivPic.setImageBitmap(result);
     mLocalCacheUtils.setBitmapToLocal(url, result);// 将图片保存在本地
     mMemoryCacheUtils.setBitmapToMemory(url, result);// 将图片保存在内存
     System.out.println("从网络缓存读取图片啦...");
   }
 }
      }
    }

    
    private Bitmap downloadBitmap(String url) {

      HttpURLConnection conn = null;
      try {
 conn = (HttpURLConnection) new URL(url).openConnection();

 conn.setConnectTimeout(5000);
 conn.setReadTimeout(5000);
 conn.setRequestMethod("GET");
 conn.connect();

 int responseCode = conn.getResponseCode();
 if (responseCode == 200) {
   InputStream inputStream = conn.getInputStream();

   //图片压缩处理
   BitmapFactory.Options option = new BitmapFactory.Options();
   option.inSampleSize = 2;//宽高都压缩为原来的二分之一, 此参数需要根据图片要展示的大小来确定
   option.inPreferredConfig = Bitmap.Config.RGB_565;//设置图片格式

   Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, option);
   return bitmap;
 }

      } catch (Exception e) {
 e.printStackTrace();
      } finally {
 conn.disconnect();
      }

      return null;
    }
  }

本地缓存

两个方法:设置本地缓存,获取本地缓存

  public class LocalCacheUtils {

    public static final String CACHE_PATH = Environment
 .getExternalStorageDirectory().getAbsolutePath() + "/local_cache";

    
    public Bitmap getBitmapFromLocal(String url) {
      try {
 String fileName = MD5Encoder.encode(url);
 File file = new File(CACHE_PATH, fileName);

 if (file.exists()) {
   Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
file));
   return bitmap;
 }

      } catch (Exception e) {
 e.printStackTrace();
      }

      return null;
    }

    
    public void setBitmapToLocal(String url, Bitmap bitmap) {
      try {
 String fileName = MD5Encoder.encode(url);

 File file = new File(CACHE_PATH, fileName);

 File parentFile = file.getParentFile();
 if (!parentFile.exists()) {// 如果文件夹不存在, 创建文件夹
   parentFile.mkdirs();
 }

 // 将图片保存在本地
 bitmap.compress(CompressFormat.JPEG, 100,
     new FileOutputStream(file));
      } catch (Exception e) {
 e.printStackTrace();
      }

    }
  }

内存缓存

两个方法:设置内存缓存,获取内存缓存

问题:

如果使用HashMap存储图片时,当图片越来越多时,会导致内存溢出,因为它是强引用,java的垃圾回收器不会回收。

如若改成软引用SoftReference(内存不够时,垃圾回收器会考虑回收),仍有一个问题:在android2.3+, 系统会优先将SoftReference的对象提前回收掉, 即使内存够用。

解决办法:可以用LruCache来解决上述内存不回收或提前回收的问题。least recentlly use 最少最近使用算法 它会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定
 

    public class MemoryCacheUtils {

      // private HashMap> mMemoryCache = new
      // HashMap>();
      private LruCache mMemoryCache;

      public MemoryCacheUtils() {
 long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模拟器默认是16M
 mMemoryCache = new LruCache((int) maxMemory) {
   @Override
   protected int sizeOf(String key, Bitmap value) {
     int byteCount = value.getRowBytes() * value.getHeight();// 获取图片占用内存大小
     return byteCount;
   }
 };
      }

      
      public Bitmap getBitmapFromMemory(String url) {
 // SoftReference softReference = mMemoryCache.get(url);
 // if (softReference != null) {
 // Bitmap bitmap = softReference.get();
 // return bitmap;
 // }
 return mMemoryCache.get(url);
      }

      
      public void setBitmapToMemory(String url, Bitmap bitmap) {
 // SoftReference softReference = new
 // SoftReference(bitmap);
 // mMemoryCache.put(url, softReference);
 mMemoryCache.put(url, bitmap);
      }
    }

图片压缩

  //图片压缩处理(在从网络获取图片的时候就进行压缩)
  BitmapFactory.Options option = new BitmapFactory.Options();
  option.inSampleSize = 2;//宽高都压缩为原来的二分之一, 此参数需要根据图片要展示的大小来确定
  option.inPreferredConfig = Bitmap.Config.RGB_565;//设置图片格式
  Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, option);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/160426.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号