Using disk cache with Volley and ListView really slow

218 views Asked by At

I am trying to use this library https://github.com/JakeWharton/DiskLruCache for disk cache but I'm having problems when I have a lot of images in my ListView. The lag is really bad sometimes.

I've used the following approach like from this GitHub repo: https://github.com/rdrobinson3/VolleyImageCacheExample

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 ), IO_BUFFER_SIZE );
        return bitmap.compress( mCompressFormat, mCompressQuality, out );
    } finally {
        if ( out != null ) {
            out.close();
        }
    }
}

private File getDiskCacheDir(Context context, String uniqueName) {

    final String cachePath = context.getCacheDir().getPath();
    return new File(cachePath + File.separator + uniqueName);
}

@Override
public void putBitmap( 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) {
        }           
    }

}

@Override
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, 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;

}

The problem is that for bigger images, there is a big lag and there is no good scrolling experience.

How can I improve this approach?

I can do public Bitmap putBitmap( String key ) to save bitmap in background thread but there is a problem with public Bitmap getBitmap( String key ) which can't be done in background thread.

Thank you.

0

There are 0 answers