Have anyone worked on DiskLruCache?
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
provides an example of using this caching method. But i observe the implementation for DiskLruCache in 4.0 source code does not have defined methods. Any idea how to use this?
You can use Picasso as image loader.
Or
This is what I did:
I created a class named DiskLruImageCache with a DiskLruCache (the one from Jake Wharton) object and the same methods in the simple implementation on the dev guide (displaying bitmaps efficiently):
public class DiskLruImageCache {
private DiskLruCache mDiskCache;
private CompressFormat mCompressFormat = CompressFormat.JPEG;
private int mCompressQuality = 70;
private static final int APP_VERSION = 1;
private static final int VALUE_COUNT = 1;
private static final String TAG = "DiskLruImageCache";
public DiskLruImageCache( Context context,String uniqueName, int diskCacheSize,
CompressFormat compressFormat, int quality ) {
try {
final File diskCacheDir = getDiskCacheDir(context, uniqueName );
mDiskCache = DiskLruCache.open( diskCacheDir, APP_VERSION, VALUE_COUNT, diskCacheSize );
mCompressFormat = compressFormat;
mCompressQuality = quality;
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean writeBitmapToFile( Bitmap bitmap, DiskLruCache.Editor editor )
throws IOException, FileNotFoundException {
OutputStream out = null;
try {
out = new BufferedOutputStream( editor.newOutputStream( 0 ), Utils.IO_BUFFER_SIZE );
return bitmap.compress( mCompressFormat, mCompressQuality, out );
} finally {
if ( out != null ) {
out.close();
}
}
}
private 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()) ||
!Utils.isExternalStorageRemovable() ?
Utils.getExternalCacheDir(context).getPath() :
context.getCacheDir().getPath();
return new File(cachePath + File.separator + uniqueName);
}
public void put( String key, Bitmap data ) {
DiskLruCache.Editor editor = null;
try {
editor = mDiskCache.edit( key );
if ( editor == null ) {
return;
}
if( writeBitmapToFile( data, editor ) ) {
mDiskCache.flush();
editor.commit();
if ( BuildConfig.DEBUG ) {
Log.d( "cache_test_DISK_", "image put on disk cache " + key );
}
} else {
editor.abort();
if ( BuildConfig.DEBUG ) {
Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
}
}
} catch (IOException e) {
if ( BuildConfig.DEBUG ) {
Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
}
try {
if ( editor != null ) {
editor.abort();
}
} catch (IOException ignored) {
}
}
}
public Bitmap getBitmap( String key ) {
Bitmap bitmap = null;
DiskLruCache.Snapshot snapshot = null;
try {
snapshot = mDiskCache.get( key );
if ( snapshot == null ) {
return null;
}
final InputStream in = snapshot.getInputStream( 0 );
if ( in != null ) {
final BufferedInputStream buffIn =
new BufferedInputStream( in, Utils.IO_BUFFER_SIZE );
bitmap = BitmapFactory.decodeStream( buffIn );
}
} catch ( IOException e ) {
e.printStackTrace();
} finally {
if ( snapshot != null ) {
snapshot.close();
}
}
if ( BuildConfig.DEBUG ) {
Log.d( "cache_test_DISK_", bitmap == null ? "" : "image read from disk " + key);
}
return bitmap;
}
public boolean containsKey( String key ) {
boolean contained = false;
DiskLruCache.Snapshot snapshot = null;
try {
snapshot = mDiskCache.get( key );
contained = snapshot != null;
} catch (IOException e) {
e.printStackTrace();
} finally {
if ( snapshot != null ) {
snapshot.close();
}
}
return contained;
}
public void clearCache() {
if ( BuildConfig.DEBUG ) {
Log.d( "cache_test_DISK_", "disk cache CLEARED");
}
try {
mDiskCache.delete();
} catch ( IOException e ) {
e.printStackTrace();
}
}
public File getCacheFolder() {
return mDiskCache.getDirectory();
}
}
Utils source code is:
public class Utils {
public static final int IO_BUFFER_SIZE = 8 * 1024;
private Utils() {};
public static boolean isExternalStorageRemovable() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
return Environment.isExternalStorageRemovable();
}
return true;
}
public static File getExternalCacheDir(Context context) {
if (hasExternalCacheDir()) {
return context.getExternalCacheDir();
}
// Before Froyo we need to construct the external cache dir ourselves
final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
}
public static boolean hasExternalCacheDir() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}
}
Remember to put
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
on your AndroidManifest.xml
I figured out this way by reading this code and the javadoc from Jake Wharton's DiskLruCache
You can also use the SimpleDiskCache, which wraps the DiskLruCache with more developer friendly interface.
I wrote a library based on this nice piece of code posted by @Platonius. It includes some bug fixes, for example frequent IOExceptions in the put() method with "failed to delete file". It uses both LRU and disk cache: https://github.com/felipecsl/Android-ImageManager
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With