android三级缓存详解
16lz
2021-01-23
为什么需要图片缓存
android默认给每个应用只分配16M的内存,所以如果加载过多的图片,为了防止内存溢出,应该将图片缓存起来。图片的三级缓存分别是: 内存缓存 本地缓存 网络缓存其中,内存缓存应优先加载,它速度最快;本地缓存次优先加载,它速度也快;网络缓存不应该优先加载,它走网络,速度慢且耗流量。(总的来说由快到慢)
三级缓存的具体实现
网络缓存
根据图片的url去加载图片 在本地和内存中缓存 public class NetCacheUtils { private LocalCacheUtils mLocalCacheUtils; private MemoryCacheUtils mMemoryCacheUtils; public NetCacheUtils(LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) { mLocalCacheUtils = localCacheUtils; mMemoryCacheUtils = memoryCacheUtils; } /** * 从网络下载图片 * * @param ivPic * @param url */ public void getBitmapFromNet(ImageView ivPic, String url) { new BitmapTask().execute(ivPic, url);// 启动AsyncTask, // 参数会在doInbackground中获取 } /** * Handler和线程池的封装 * * 第一个泛型: 参数类型 第二个泛型: 更新进度的泛型, 第三个泛型是onPostExecute的返回结果 * * */ class BitmapTask extends AsyncTask
本地缓存
两个方法:设置本地缓存,获取本地缓存
public class LocalCacheUtils { public static final String CACHE_PATH = Environment .getExternalStorageDirectory().getAbsolutePath() + "/local_cache"; /** * 从本地sdcard读图片 */ 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; } /** * 向sdcard写图片 * * @param url * @param bitmap */ 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; } }; } /** * 从内存读 * * @param url */ public Bitmap getBitmapFromMemory(String url) { // SoftReference softReference = mMemoryCache.get(url); // if (softReference != null) { // Bitmap bitmap = softReference.get(); // return bitmap; // } return mMemoryCache.get(url); } /** * 写内存 * * @param url * @param bitmap */ 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);
转载出处:http://blog.csdn.net/sinat_20645961/article/details/46325243
更多相关文章
- Android内存泄露及分析
- Android上的内存分配策略优化
- Android中Nine-Patch(.9)图片介绍与制作
- 浅谈如何避免Android内存溢出
- android/IOS常用图片上传的两种方式
- Android拍照和图片处理类应用盘点