Last active
September 17, 2017 23:41
-
-
Save yaronv/24324e0a92373589618f to your computer and use it in GitHub Desktop.
Google's best practice for caching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private DiskLruCache mDiskLruCache; | |
private final Object mDiskCacheLock = new Object(); | |
private boolean mDiskCacheStarting = true; | |
private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB | |
private static final String DISK_CACHE_SUBDIR = "thumbnails"; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
... | |
// Initialize memory cache | |
... | |
// Initialize disk cache on background thread | |
File cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR); | |
new InitDiskCacheTask().execute(cacheDir); | |
... | |
} | |
class InitDiskCacheTask extends AsyncTask<File, Void, Void> { | |
@Override | |
protected Void doInBackground(File... params) { | |
synchronized (mDiskCacheLock) { | |
File cacheDir = params[0]; | |
mDiskLruCache = DiskLruCache.open(cacheDir, DISK_CACHE_SIZE); | |
mDiskCacheStarting = false; // Finished initialization | |
mDiskCacheLock.notifyAll(); // Wake any waiting threads | |
} | |
return null; | |
} | |
} | |
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { | |
... | |
// Decode image in background. | |
@Override | |
protected Bitmap doInBackground(Integer... params) { | |
final String imageKey = String.valueOf(params[0]); | |
// Check disk cache in background thread | |
Bitmap bitmap = getBitmapFromDiskCache(imageKey); | |
if (bitmap == null) { // Not found in disk cache | |
// Process as normal | |
final Bitmap bitmap = decodeSampledBitmapFromResource( | |
getResources(), params[0], 100, 100)); | |
} | |
// Add final bitmap to caches | |
addBitmapToCache(imageKey, bitmap); | |
return bitmap; | |
} | |
... | |
} | |
public void addBitmapToCache(String key, Bitmap bitmap) { | |
// Add to memory cache as before | |
if (getBitmapFromMemCache(key) == null) { | |
mMemoryCache.put(key, bitmap); | |
} | |
// Also add to disk cache | |
synchronized (mDiskCacheLock) { | |
if (mDiskLruCache != null && mDiskLruCache.get(key) == null) { | |
mDiskLruCache.put(key, bitmap); | |
} | |
} | |
} | |
public Bitmap getBitmapFromDiskCache(String key) { | |
synchronized (mDiskCacheLock) { | |
// Wait while disk cache is started from background thread | |
while (mDiskCacheStarting) { | |
try { | |
mDiskCacheLock.wait(); | |
} catch (InterruptedException e) {} | |
} | |
if (mDiskLruCache != null) { | |
return mDiskLruCache.get(key); | |
} | |
} | |
return null; | |
} | |
// Creates a unique subdirectory of the designated app cache directory. Tries to use external | |
// but if not mounted, falls back on internal storage. | |
public static File getDiskCacheDir(Context context, String uniqueName) { | |
// Check if media is mounted or storage is built-in, if so, try and use external cache dir | |
// otherwise use internal cache dir | |
final String cachePath = | |
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || | |
!isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() : | |
context.getCacheDir().getPath(); | |
return new File(cachePath + File.separator + uniqueName); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 64 is calling a method that doesn't exist in
DiskLruCache
. The official documentation also has the same error.