Using Disklrucache in Android 4.0 Does Not Provide for Opencache Method

Using DiskLruCache in android 4.0 does not provide for openCache method

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

android DiskLruCache implementation

  1. The signature of the API is a hint that you should read/write from the Cache as if it's an interface to disk. So to answer your question more directly - yes, you should call get() and put() in a thread separate from the main looper.

  2. Always be sympathetic to the user, and don't take more than you need. An appropriate size will depend on the nature of your application. Are you caching a large number of small bitmaps, or a small number of large images? How often do the images change? Are you planning on using an in-memory cache alongside the disk cache? Thinking about these questions will help you come to an appropriate specification that can drive your decision. Alternatively, you can start with a small number (maybe 4mb) and use some logging and/or metrics to measure the amount of cache misses and tweak from there.

  3. Finally, you should specify the number in bytes. E.g.

    DISK_CACHE_SIZE = 1024 * 1024 * 16; // 16mb in bytes

Example of JakeWhartons DiskLruCache

I used getBitmap() in the sample someone posted here.

This is the answer you're looking for under a different title. You will have to create a Utils for some of the code but it's pretty straightforward.

Good Luck!

Using DiskLruCache in android 4.0 does not provide for openCache method

Load GridLayout images according to available memory

I've had such problem (need to load more than 100 high-res images to ListView and cache them). I've used DiskLruCache library (https://github.com/JakeWharton/DiskLruCache) for it in a way described here:

Using DiskLruCache in android 4.0 does not provide for openCache method

Works perfectly.



Related Topics



Leave a reply



Submit