Adjust cache
This commit is contained in:
1 parent
af8c480588
commit
6d8d16d1f8
2 files changed
+76
-113
No files matched your search
+32
-67
@@ -17,8 +17,11 @@
|
||||
package com.hippo.ehviewer.cache;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.LruCache;
|
||||
|
||||
import com.hippo.ehviewer.util.Log;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
@@ -28,10 +31,12 @@ import java.io.OutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class AnyCache<V> {
|
||||
public abstract class AnyCache<V> {
|
||||
|
||||
private LruCache<String, V> mMemoryCache;
|
||||
private DiskCache<V> mDiskCache;
|
||||
private static final String TAG = AnyCache.class.getSimpleName();
|
||||
|
||||
private @Nullable LruCache<String, V> mMemoryCache;
|
||||
private @Nullable DiskCache<V> mDiskCache;
|
||||
|
||||
/**
|
||||
* Used to temporarily pause the disk cache while scrolling
|
||||
@@ -39,19 +44,21 @@ public class AnyCache<V> {
|
||||
public boolean mPauseDiskAccess = false;
|
||||
private final Object mPauseLock = new Object();
|
||||
|
||||
private AnyCache(Builder builder) {
|
||||
if (builder.mMemoryCacheMaxSize > 0 && builder.mMemoryCacheHelper != null) {
|
||||
mMemoryCache = new MemoryCahce<V>(
|
||||
builder.mMemoryCacheMaxSize, builder.mMemoryCacheHelper);
|
||||
}
|
||||
if (builder.mDiskCacheDir != null && builder.mDiskCacheMaxSize > 0 &&
|
||||
builder.mDiskCacheHelper != null) {
|
||||
try {
|
||||
mDiskCache = new DiskCache<V>(
|
||||
builder.mDiskCacheDir, builder.mDiskCacheMaxSize, builder.mDiskCacheHelper);
|
||||
} catch (IOException e) {
|
||||
// Can't create disk cache
|
||||
}
|
||||
protected abstract int sizeOf(String key, V value);
|
||||
|
||||
protected abstract V read(InputStream is);
|
||||
|
||||
protected abstract boolean write(OutputStream os, V value);
|
||||
|
||||
public void setMemoryCache(int maxSize) {
|
||||
mMemoryCache = new MemoryCahce<V>(maxSize, this);
|
||||
}
|
||||
|
||||
public void setDiskCache(File cacheDir, int maxSize) {
|
||||
try {
|
||||
mDiskCache = new DiskCache<V>(cacheDir, maxSize, this);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Can't create disk cache", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,68 +278,32 @@ public class AnyCache<V> {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private int mMemoryCacheMaxSize;
|
||||
private MemoryCacheHelper mMemoryCacheHelper;
|
||||
|
||||
private File mDiskCacheDir;
|
||||
private int mDiskCacheMaxSize;
|
||||
private DiskCacheHelper mDiskCacheHelper;
|
||||
|
||||
public Builder setMemoryCache(int maxSize, MemoryCacheHelper helper) {
|
||||
mMemoryCacheMaxSize = maxSize;
|
||||
mMemoryCacheHelper = helper;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this dir to store disk cache.
|
||||
*
|
||||
* @param cacheDir this dir to store disk cache, null for no disk cache
|
||||
* @return the Builder
|
||||
*/
|
||||
public Builder setDiskCache(File cacheDir, int maxSize, DiskCacheHelper helper) {
|
||||
mDiskCacheDir = cacheDir;
|
||||
mDiskCacheMaxSize = maxSize;
|
||||
mDiskCacheHelper = helper;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnyCache build() {
|
||||
return new AnyCache(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class MemoryCahce<E> extends LruCache<String, E> {
|
||||
|
||||
private MemoryCacheHelper<E> mHelper;
|
||||
public AnyCache<E> mParent;
|
||||
|
||||
public MemoryCahce(int maxSize, MemoryCacheHelper<E> helper) {
|
||||
public MemoryCahce(int maxSize, AnyCache<E> parent) {
|
||||
super(maxSize);
|
||||
mHelper = helper;
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int sizeOf(String key, E value) {
|
||||
return mHelper.sizeOf(key, value);
|
||||
return mParent.sizeOf(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class MemoryCacheHelper<E> {
|
||||
public abstract int sizeOf(String key, E value);
|
||||
}
|
||||
|
||||
public static class DiskCache<E> {
|
||||
|
||||
private static final int IO_BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
public DiskLruCache mDiskLruCache;
|
||||
public DiskCacheHelper<E> mHelper;
|
||||
public AnyCache<E> mParent;
|
||||
|
||||
public DiskCache(File cacheDir, int size, DiskCacheHelper<E> helper) throws IOException {
|
||||
public DiskCache(File cacheDir, int size, AnyCache<E> parent) throws IOException {
|
||||
mDiskLruCache = DiskLruCache.open(cacheDir, 1, 1, size);
|
||||
mHelper = helper;
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
public E get(String key) {
|
||||
@@ -348,7 +319,7 @@ public class AnyCache<V> {
|
||||
if (in != null) {
|
||||
final BufferedInputStream buffIn =
|
||||
new BufferedInputStream(in, IO_BUFFER_SIZE);
|
||||
return mHelper.get(buffIn);
|
||||
return mParent.read(buffIn);
|
||||
} else {
|
||||
// Can't get InputStream
|
||||
return null;
|
||||
@@ -375,7 +346,7 @@ public class AnyCache<V> {
|
||||
if (os != null) {
|
||||
final BufferedOutputStream buffOut =
|
||||
new BufferedOutputStream(os, IO_BUFFER_SIZE);
|
||||
boolean result = mHelper.put(buffOut, value);
|
||||
boolean result = mParent.write(buffOut, value);
|
||||
mDiskLruCache.flush();
|
||||
editor.commit();
|
||||
return result;
|
||||
@@ -396,10 +367,4 @@ public class AnyCache<V> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class DiskCacheHelper<E> {
|
||||
public abstract E get(InputStream is);
|
||||
|
||||
public abstract boolean put(OutputStream os, E value);
|
||||
}
|
||||
}
|
||||
+44
-46
@@ -21,12 +21,13 @@ import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class ImageCache {
|
||||
public class ImageCache extends AnyCache<Bitmap>{
|
||||
|
||||
private static final String TAG = "ImageCache";
|
||||
|
||||
@@ -45,38 +46,59 @@ public class ImageCache {
|
||||
*/
|
||||
private static final int COMPRESS_QUALITY = 98;
|
||||
|
||||
private static AnyCache<Bitmap> sImageCache;
|
||||
private static ImageCache sImageCache;
|
||||
|
||||
public static AnyCache<Bitmap> getImageCache(Context context) {
|
||||
public static @NonNull ImageCache getImageCache(@NonNull Context context) {
|
||||
if (sImageCache == null) {
|
||||
AnyCache.Builder builder = new AnyCache.Builder();
|
||||
|
||||
final ActivityManager activityManager = (ActivityManager)context
|
||||
.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
final int memoryCacheMax = Math.round(MEM_CACHE_DIVIDER * activityManager.getMemoryClass()
|
||||
* 1024 * 1024);
|
||||
builder.setMemoryCache(memoryCacheMax, new BitmapMemoryCacheHelper());
|
||||
|
||||
File diskCacheDir = getDiskCacheDir(context, TAG);
|
||||
if (diskCacheDir != null) {
|
||||
if (!diskCacheDir.exists()) {
|
||||
diskCacheDir.mkdirs();
|
||||
}
|
||||
builder.setDiskCache(diskCacheDir, 20 * 1024 * 1024, new BitmapDiskCacheHelper());
|
||||
}
|
||||
|
||||
sImageCache = builder.build();
|
||||
sImageCache = new ImageCache(context.getApplicationContext());
|
||||
}
|
||||
return sImageCache;
|
||||
}
|
||||
|
||||
|
||||
private ImageCache(Context context) {
|
||||
final ActivityManager activityManager = (ActivityManager)context
|
||||
.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
final int memoryCacheMax = Math.round(MEM_CACHE_DIVIDER * activityManager.getMemoryClass()
|
||||
* 1024 * 1024);
|
||||
setMemoryCache(memoryCacheMax);
|
||||
|
||||
File diskCacheDir = getDiskCacheDir(context, TAG);
|
||||
if (diskCacheDir != null) {
|
||||
if (!diskCacheDir.exists()) {
|
||||
diskCacheDir.mkdirs();
|
||||
}
|
||||
setDiskCache(diskCacheDir, 20 * 1024 * 1024);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int sizeOf(String key, Bitmap value) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
return value.getAllocationByteCount();
|
||||
} else {
|
||||
return value.getByteCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Bitmap read(InputStream is) {
|
||||
return BitmapFactory.decodeStream(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean write(OutputStream os, Bitmap value) {
|
||||
return value.compress(COMPRESS_FORMAT, COMPRESS_QUALITY, os);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the external app cache directory
|
||||
*
|
||||
* @param context The {@link Context} to use
|
||||
* @return The external cache directory
|
||||
*/
|
||||
public static File getExternalCacheDir(final Context context) {
|
||||
private static File getExternalCacheDir(final Context context) {
|
||||
return context.getExternalCacheDir();
|
||||
}
|
||||
|
||||
@@ -88,35 +110,11 @@ public class ImageCache {
|
||||
* directory
|
||||
* @return The cache directory
|
||||
*/
|
||||
public static File getDiskCacheDir(final Context context, final String uniqueName) {
|
||||
private static File getDiskCacheDir(final Context context, final String uniqueName) {
|
||||
// getExternalCacheDir(context) returns null if external storage is not ready
|
||||
final String cachePath = getExternalCacheDir(context) != null
|
||||
? getExternalCacheDir(context).getPath()
|
||||
: context.getCacheDir().getPath();
|
||||
return new File(cachePath, uniqueName);
|
||||
}
|
||||
|
||||
private static class BitmapMemoryCacheHelper extends AnyCache.MemoryCacheHelper<Bitmap> {
|
||||
@Override
|
||||
public int sizeOf(String key, android.graphics.Bitmap bitmap) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
return bitmap.getAllocationByteCount();
|
||||
} else {
|
||||
return bitmap.getByteCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class BitmapDiskCacheHelper extends AnyCache.DiskCacheHelper<Bitmap> {
|
||||
@Override
|
||||
public Bitmap get(InputStream is) {
|
||||
return BitmapFactory.decodeStream(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(OutputStream os, Bitmap value) {
|
||||
value.compress(COMPRESS_FORMAT, COMPRESS_QUALITY, os);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user