cache-2
来源:互联网 发布:白苹果怎么备份数据 编辑:程序博客网 时间:2024/05/22 13:02
2/2:Disk Cache(磁盘中的Cache)
前面已经提到,Memory Cache的优点是读写非常快。但它的缺点就是容量太小了,而且不能持久化,所以在用户在滑动GridView时它很快会被用完,而且切换多个界面时或者是关闭程序重新打开后,再次进入原来的界面,Memory Cache是无能为力的。这个时候,我们就要用到Disk Cache了。
Disk Cache将缓存的数据放在磁盘中,因此不论用户是频繁切换界面,还是关闭程序,Disk Cache是不会消失的。
实际上,Android SDK中并没有一个类来实现Disk Cache这样的功能。但google其实已经提供了实现代码:DiskLruCache。我们只要把它搬到自己的项目中就可以了。
下面请看一段使用DiskLruCache来配合Memory Cache进行图片缓存的代码:
private DiskLruCache mDiskLruCache;private final Object mDiskCacheLock = new Object();private boolean mDiskCacheStarting = true;private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MBprivate static final String DISK_CACHE_SUBDIR = "thumbnails";@Overrideprotected void onCreate(Bundle savedInstanceState) {//...// 初始化memory cache//...// 开启后台线程初始化disk cacheFile cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR);new InitDiskCacheTask().execute(cacheDir);}class InitDiskCacheTask extends AsyncTask<File, Void, Void> {@Overrideprotected Void doInBackground(File... params) {synchronized (mDiskCacheLock) {File cacheDir = params[0];mDiskLruCache = DiskLruCache.open(cacheDir, DISK_CACHE_SIZE);mDiskCacheStarting = false; // 初始化完成mDiskCacheLock.notifyAll(); // 唤醒被hold住的线程}return null;}}class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {// 在后台加载图片@Overrideprotected Bitmap doInBackground(Integer... params) {final String imageKey = String.valueOf(params[0]);// 通过后台线程检查disk cacheBitmap bitmap = getBitmapFromDiskCache(imageKey);if (bitmap == null) { // 如果没有在disk cache中发现这个bitmap// 加载这个bitmapfinal Bitmap bitmap = decodeSampledBitmapFromResource(getResources(), params[0], 100, 100));}// 把这个bitmap加入cacheaddBitmapToCache(imageKey, bitmap);return bitmap;}}public void addBitmapToCache(String key, Bitmap bitmap) {// 把bitmap加入memory cacheif (getBitmapFromMemCache(key) == null) {mMemoryCache.put(key, bitmap);}// 同样,也加入disk cachesynchronized (mDiskCacheLock) {if (mDiskLruCache != null && mDiskLruCache.get(key) == null) {mDiskLruCache.put(key, bitmap);}}}public Bitmap getBitmapFromDiskCache(String key) {synchronized (mDiskCacheLock) {// 等待disk cache初始化完毕while (mDiskCacheStarting) {try {mDiskCacheLock.wait();} catch (InterruptedException e) {}}if (mDiskLruCache != null) {return mDiskLruCache.get(key);}}return null;}// 在自带的cache目录下建立一个独立的子目录。优先使用外置存储。但如果外置存储不存在,使用内置存储。public static File getDiskCacheDir(Context context, String uniqueName) {// 如果MEDIA目录已经挂载或者外置存储是手机自带的(Nexus设备都这么干),使用外置存储;否则使用内置存储final String cachePath =Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||!isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() :context.getCacheDir().getPath();return new File(cachePath + File.separator + uniqueName);}
提示:由于disk cache的初始化是耗时操作,所以这个过程被放在了后台进程。而由此导致的结果是,主线程有可能在它初始化完成之前就尝试读取disk cache,这会导致程序出错。因此以上代码中使用了synchronized关键字和一个lock对象来确保在初始化完成之前disk cache不会被访问。(什么是synchronized?文章最后会有介绍)
上面这段代码看起来比较多,但大致读一下就会发现,它的思路非常简单:1.读取cache的时候,优先读取memory cache,读不到的时候再读取disk cache;2.把bitmap保存到cache中的时候,memory cache和disk cache都要保存。
0 0
- cache-2
- Cache工作原理-2
- 9.4.2 二级Cache
- solr cache 2
- cache
- cache
- Cache
- cache
- Cache
- Cache
- Cache
- Cache
- cache
- cache
- cache
- Cache
- cache
- cache
- 百度地图-设置中性点坐标
- An internal error occurred during: "Redeploy". Cannot change deployment state from ERROR to REDEPLOY
- 百度地图SDK5-基本设置
- cache-1
- Async Task的使用详解
- cache-2
- ion学习
- git-appraise
- 4种安卓自带的HTTP通讯方式(只是例子,网络通讯就随便写在主线)
- cp的使用注意事项
- Android有效解决加载大图片时内存溢出的问题
- java移位运算符:<<(左移)、>>(带符号右移)和>>>(无符号右移)
- 隐藏安卓软键盘
- popuWindow相关知识