• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.bitmapfun.util;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Bitmap.CompressFormat;
22 import android.support.v4.app.FragmentActivity;
23 import android.support.v4.util.LruCache;
24 import android.util.Log;
25 
26 import com.example.android.bitmapfun.BuildConfig;
27 
28 import java.io.File;
29 
30 /**
31  * This class holds our bitmap caches (memory and disk).
32  */
33 public class ImageCache {
34     private static final String TAG = "ImageCache";
35 
36     // Default memory cache size
37     private static final int DEFAULT_MEM_CACHE_SIZE = 1024 * 1024 * 5; // 5MB
38 
39     // Default disk cache size
40     private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
41 
42     // Compression settings when writing images to disk cache
43     private static final CompressFormat DEFAULT_COMPRESS_FORMAT = CompressFormat.JPEG;
44     private static final int DEFAULT_COMPRESS_QUALITY = 70;
45 
46     // Constants to easily toggle various caches
47     private static final boolean DEFAULT_MEM_CACHE_ENABLED = true;
48     private static final boolean DEFAULT_DISK_CACHE_ENABLED = true;
49     private static final boolean DEFAULT_CLEAR_DISK_CACHE_ON_START = false;
50 
51     private DiskLruCache mDiskCache;
52     private LruCache<String, Bitmap> mMemoryCache;
53 
54     /**
55      * Creating a new ImageCache object using the specified parameters.
56      *
57      * @param context The context to use
58      * @param cacheParams The cache parameters to use to initialize the cache
59      */
ImageCache(Context context, ImageCacheParams cacheParams)60     public ImageCache(Context context, ImageCacheParams cacheParams) {
61         init(context, cacheParams);
62     }
63 
64     /**
65      * Creating a new ImageCache object using the default parameters.
66      *
67      * @param context The context to use
68      * @param uniqueName A unique name that will be appended to the cache directory
69      */
ImageCache(Context context, String uniqueName)70     public ImageCache(Context context, String uniqueName) {
71         init(context, new ImageCacheParams(uniqueName));
72     }
73 
74     /**
75      * Find and return an existing ImageCache stored in a {@link RetainFragment}, if not found a new
76      * one is created with defaults and saved to a {@link RetainFragment}.
77      *
78      * @param activity The calling {@link FragmentActivity}
79      * @param uniqueName A unique name to append to the cache directory
80      * @return An existing retained ImageCache object or a new one if one did not exist.
81      */
findOrCreateCache( final FragmentActivity activity, final String uniqueName)82     public static ImageCache findOrCreateCache(
83             final FragmentActivity activity, final String uniqueName) {
84         return findOrCreateCache(activity, new ImageCacheParams(uniqueName));
85     }
86 
87     /**
88      * Find and return an existing ImageCache stored in a {@link RetainFragment}, if not found a new
89      * one is created using the supplied params and saved to a {@link RetainFragment}.
90      *
91      * @param activity The calling {@link FragmentActivity}
92      * @param cacheParams The cache parameters to use if creating the ImageCache
93      * @return An existing retained ImageCache object or a new one if one did not exist
94      */
findOrCreateCache( final FragmentActivity activity, ImageCacheParams cacheParams)95     public static ImageCache findOrCreateCache(
96             final FragmentActivity activity, ImageCacheParams cacheParams) {
97 
98         // Search for, or create an instance of the non-UI RetainFragment
99         final RetainFragment mRetainFragment = RetainFragment.findOrCreateRetainFragment(
100                 activity.getSupportFragmentManager());
101 
102         // See if we already have an ImageCache stored in RetainFragment
103         ImageCache imageCache = (ImageCache) mRetainFragment.getObject();
104 
105         // No existing ImageCache, create one and store it in RetainFragment
106         if (imageCache == null) {
107             imageCache = new ImageCache(activity, cacheParams);
108             mRetainFragment.setObject(imageCache);
109         }
110 
111         return imageCache;
112     }
113 
114     /**
115      * Initialize the cache, providing all parameters.
116      *
117      * @param context The context to use
118      * @param cacheParams The cache parameters to initialize the cache
119      */
init(Context context, ImageCacheParams cacheParams)120     private void init(Context context, ImageCacheParams cacheParams) {
121         final File diskCacheDir = DiskLruCache.getDiskCacheDir(context, cacheParams.uniqueName);
122 
123         // Set up disk cache
124         if (cacheParams.diskCacheEnabled) {
125             mDiskCache = DiskLruCache.openCache(context, diskCacheDir, cacheParams.diskCacheSize);
126             mDiskCache.setCompressParams(cacheParams.compressFormat, cacheParams.compressQuality);
127             if (cacheParams.clearDiskCacheOnStart) {
128                 mDiskCache.clearCache();
129             }
130         }
131 
132         // Set up memory cache
133         if (cacheParams.memoryCacheEnabled) {
134             mMemoryCache = new LruCache<String, Bitmap>(cacheParams.memCacheSize) {
135                 /**
136                  * Measure item size in bytes rather than units which is more practical for a bitmap
137                  * cache
138                  */
139                 @Override
140                 protected int sizeOf(String key, Bitmap bitmap) {
141                     return Utils.getBitmapSize(bitmap);
142                 }
143             };
144         }
145     }
146 
addBitmapToCache(String data, Bitmap bitmap)147     public void addBitmapToCache(String data, Bitmap bitmap) {
148         if (data == null || bitmap == null) {
149             return;
150         }
151 
152         // Add to memory cache
153         if (mMemoryCache != null && mMemoryCache.get(data) == null) {
154             mMemoryCache.put(data, bitmap);
155         }
156 
157         // Add to disk cache
158         if (mDiskCache != null && !mDiskCache.containsKey(data)) {
159             mDiskCache.put(data, bitmap);
160         }
161     }
162 
163     /**
164      * Get from memory cache.
165      *
166      * @param data Unique identifier for which item to get
167      * @return The bitmap if found in cache, null otherwise
168      */
getBitmapFromMemCache(String data)169     public Bitmap getBitmapFromMemCache(String data) {
170         if (mMemoryCache != null) {
171             final Bitmap memBitmap = mMemoryCache.get(data);
172             if (memBitmap != null) {
173                 if (BuildConfig.DEBUG) {
174                     Log.d(TAG, "Memory cache hit");
175                 }
176                 return memBitmap;
177             }
178         }
179         return null;
180     }
181 
182     /**
183      * Get from disk cache.
184      *
185      * @param data Unique identifier for which item to get
186      * @return The bitmap if found in cache, null otherwise
187      */
getBitmapFromDiskCache(String data)188     public Bitmap getBitmapFromDiskCache(String data) {
189         if (mDiskCache != null) {
190             return mDiskCache.get(data);
191         }
192         return null;
193     }
194 
clearCaches()195     public void clearCaches() {
196         mDiskCache.clearCache();
197         mMemoryCache.evictAll();
198     }
199 
200     /**
201      * A holder class that contains cache parameters.
202      */
203     public static class ImageCacheParams {
204         public String uniqueName;
205         public int memCacheSize = DEFAULT_MEM_CACHE_SIZE;
206         public int diskCacheSize = DEFAULT_DISK_CACHE_SIZE;
207         public CompressFormat compressFormat = DEFAULT_COMPRESS_FORMAT;
208         public int compressQuality = DEFAULT_COMPRESS_QUALITY;
209         public boolean memoryCacheEnabled = DEFAULT_MEM_CACHE_ENABLED;
210         public boolean diskCacheEnabled = DEFAULT_DISK_CACHE_ENABLED;
211         public boolean clearDiskCacheOnStart = DEFAULT_CLEAR_DISK_CACHE_ON_START;
212 
ImageCacheParams(String uniqueName)213         public ImageCacheParams(String uniqueName) {
214             this.uniqueName = uniqueName;
215         }
216     }
217 }
218