博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Android开发]三级缓存初探索
阅读量:2441 次
发布时间:2019-05-10

本文共 7365 字,大约阅读时间需要 24 分钟。

三级缓存:

内存缓存:优先加载,速度最快
本地内存:速度其次,内存没有,读本地
网络缓存:速度最慢,本地也没有,才访问网络

我们定义一个图片加载类:

MyBitmapUtils.java

/** * 自定义图片加载工具 * @author dream * */public class MyBitmapUtils {
NetCacheUtils mNetCacheUtils; LocalCacheUtils mLocalCacheUtils; MemoryCacheUtils mMemoryCacheUtils; public MyBitmapUtils() { mMemoryCacheUtils = new MemoryCacheUtils(); mLocalCacheUtils = new LocalCacheUtils(); mNetCacheUtils = new NetCacheUtils(mLocalCacheUtils,mMemoryCacheUtils); } public void display(ImageView ivPic, String url) { ivPic.setImageResource(R.drawable.news_pic_default); Bitmap bitmap = null; bitmap = mMemoryCacheUtils.getBitmapFromMemory(url); if(bitmap != null) { ivPic.setImageBitmap(bitmap); return; } //从本地读 bitmap = mLocalCacheUtils.getBitmapFromLocal(url); if(bitmap != null) { ivPic.setImageBitmap(bitmap); mMemoryCacheUtils.setBitmapToMemory(url, bitmap); //将图片保存在内存 return; } //从过网络读 mNetCacheUtils.getBitmapFromNet(ivPic, url); }}

从网络获取的类:

NetCacheUtils.java

/** * 网络缓存 * @author dream * */public class NetCacheUtils {
private HttpURLConnection conn = null; private LocalCacheUtils mLocalCacheUtils; private MemoryCacheUtils mMemoryCacheUtils; public NetCacheUtils(LocalCacheUtils mLocalCacheUtils, MemoryCacheUtils mMemoryCacheUtils) { this.mLocalCacheUtils = mLocalCacheUtils; this.mMemoryCacheUtils = mMemoryCacheUtils; } /** * 从网络下载图片 * @param ivPic * @param url */ public void getBitmapFromNet(ImageView ivPic, String url) { new BitmapTask().execute(ivPic, url); //启动 AsyncTask } 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); 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); } } } } /** * 下载图片 * @param url * @return */ private Bitmap downloadBitmap(String url) { 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 options = new BitmapFactory.Options(); options.inSampleSize = 2;//宽高都压缩为原来的1/2 options.inPreferredConfig = Bitmap.Config.RGB_565; Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null, options); return bitmap; } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { conn.disconnect(); } return null; }}

从本地获取的类:

LocalCacheUtils.java

/** * 本地缓存 * @author dream * */public class LocalCacheUtils {
public static final String CACHE_PATH = Environment.getExternalStorageDirectory(). getAbsolutePath() + "/beijingwisdom"; /** * 从本地sdcard读图片 * @param url */ 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) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * 向sdcard写图片 */ 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(parentFile) ); } catch (Exception e) { e.printStackTrace(); } }}

从内存获取的类:

MemoryCacheUtils.java

/** * 内存缓存 *  * @author dream * */public class MemoryCacheUtils {
// public HashMap
> mMemoryCache = new // HashMap
>(); public 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) { mMemoryCache.put(url, bitmap); }}

内存溢出问题:

Android默认每个app只能分配16M的内存,所以经常在内存中加载图片会发生内存溢出,我们来熟悉一下Java中的引用:

强引用:垃圾回收器不会回收,Java默认引用都是强引用

软引用:SoftReference 在内存不够时,Java垃圾回收会考虑回收
弱引用:WeakReference 在内存不够时,Java垃圾回收会优先回收
虚引用:PhantomReference 在内存不够时,Java垃圾回收会最优先回收

在Android2.3+,系统会优先将SoftReference的对象提前回收,即使内存够用,所以不再使用,所以这个我们也不能用了。

接下来介绍LruCache:

least recentlly use 最近最少未使用
会将内存控制在一定的大小内,超出最大值时会自动回收,这个最大值开发者自己定。
对于界面中可以缩放的图片我们也可以进行图片压缩。

InputStream inputStream = conn .getInputStream();                //图片压缩                BitmapFactory.Options options = new BitmapFactory.Options();                options.inSampleSize = 2;//宽高都压缩为原来的1/2                options.inPreferredConfig = Bitmap.Config.RGB_565;                Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null, options);                return bitmap;

转载地址:http://eefqb.baihongyu.com/

你可能感兴趣的文章
使用MySQL内建复制功能来最佳化可用性(转)
查看>>
一个比较vista的vista主题for rf5.0fb(转)
查看>>
推荐一款 Linux 上比较漂亮的字体(转)
查看>>
在Linux中添加新的系统调用(转)
查看>>
Fedora Core 5.0 安装教程{下载}(转)
查看>>
把ACCESS的数据导入到Mysql中(转)
查看>>
shell里边子函数与主函数的实例(转)
查看>>
Linux中MAXIMA符号运算软件的简介(转)
查看>>
银行选择Linux 则无法回避高成本(转)
查看>>
上网聊天需要防范的几大威胁(转)
查看>>
[分享]后门清除完全篇(转)
查看>>
用php在linux下连接mssql2000(转)
查看>>
让你的Linux支持WEB修改密码(转)
查看>>
MYSQL的master/slave数据同步配置(转)
查看>>
一个完整的ftp远程批量shell(转)
查看>>
Vsftpd匿名无法上传,配置如下,帮忙找下原因,谢谢~!(转)
查看>>
crontab命令简介(转)
查看>>
C++中的静态联编和动态联编介绍(转)
查看>>
带有农历的日历(QT版本1752-2100)(转)
查看>>
LINUX的系统内核空间的保护(转)
查看>>