Update cache

This commit is contained in:
seven332 committed 2015-03-30 17:57:22 +08:00
1 parent e197ce3fe2
commit 4985945dcb
4 files changed
+228 -75

No files matched your search

@@ -148,7 +148,7 @@ public class AppContext extends Application implements UncaughtExceptionHandler
*/
@Override
public void onLowMemory() {
ImageCache.getImageCache(this).evictAll();
ImageCache.getImageCache(this).clearMemory();
super.onLowMemory();
}
+204 -59
View File
@@ -35,40 +35,70 @@ public abstract class AnyCache<V> {
private static final String TAG = AnyCache.class.getSimpleName();
private @Nullable LruCache<String, V> mMemoryCache;
private LruCache<String, V> mMemoryCache;
private @Nullable DiskCache<V> mDiskCache;
private final boolean mHasMemoryCache;
private final boolean mHasDiskCache;
/**
* Used to temporarily pause the disk cache while scrolling
*/
public boolean mPauseDiskAccess = false;
private final Object mPauseLock = new Object();
private final Object mDiskCacheLock = new Object();
private boolean mDiskCacheStarting = true;
public AnyCache(AnyCacheParams params) {
params.isValid();
mHasMemoryCache = params.hasMemoryCache;
mHasDiskCache = params.hasDiskCache;
if (mHasMemoryCache) {
initMemoryCache(params.memoryCacheMaxSize);
}
if (mHasDiskCache) {
initDiskCache(params.diskCacheDir, params.diskCacheMaxSize);
}
}
private void initMemoryCache(int maxSize) {
mMemoryCache = new MemoryCahce<>(maxSize, this);
}
private void initDiskCache(File cacheDir, int maxSize) {
// Set up disk cache
synchronized (mDiskCacheLock) {
try {
mDiskCache = new DiskCache<>(cacheDir, maxSize, this);
} catch (IOException e) {
Log.e(TAG, "Can't create disk cache", e);
}
// Set up disk cache finished
mDiskCacheStarting = false;
mDiskCacheLock.notifyAll();
}
}
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);
}
}
/**
* Check if have memory cache
*
* @return true if have memory cache
*/
public boolean hasMemoryCache() {
return mMemoryCache != null;
return mHasMemoryCache;
}
/**
@@ -77,7 +107,7 @@ public abstract class AnyCache<V> {
* @return true if have disk cache
*/
public boolean hasDiskCache() {
return mDiskCache != null;
return mHasDiskCache;
}
/**
@@ -87,7 +117,7 @@ public abstract class AnyCache<V> {
* @return the value you get, null for miss or no memory cache
*/
public V getFromMemory(String key) {
if (mMemoryCache != null) {
if (mHasMemoryCache) {
return mMemoryCache.get(key);
} else {
return null;
@@ -101,12 +131,26 @@ public abstract class AnyCache<V> {
* @return the value you get, null for miss or no memory cache or get error
*/
public V getFromDisk(String key) {
if (mDiskCache != null) {
if (mHasDiskCache) {
// Wait for pause
waitUntilUnpaused();
String diskKey = hashKeyForDisk(key);
return mDiskCache.get(diskKey);
synchronized (mDiskCacheLock) {
while (mDiskCacheStarting) {
try {
mDiskCacheLock.wait();
} catch (InterruptedException e) {
// Just ignore
}
}
if (mDiskCache != null) {
return mDiskCache.get(diskKey);
} else {
return null;
}
}
} else {
return null;
}
@@ -120,28 +164,22 @@ public abstract class AnyCache<V> {
* @return the value you get
*/
public V get(String key) {
V value;
if (mMemoryCache != null) {
value = mMemoryCache.get(key);
if (value != null) {
return value;
}
}
V value = getFromMemory(key);
if (mDiskCache != null) {
// Wait for pause
waitUntilUnpaused();
String diskKey = hashKeyForDisk(key);
value = mDiskCache.get(diskKey);
// Put value to memory cach
if (value != null && mMemoryCache != null) {
mMemoryCache.put(key, value);
}
if (value != null) {
// Get it in memory cache
return value;
} else {
return null;
}
value = getFromDisk(key);
if (value != null) {
// Get it in disk cache
putToMemory(key, value);
return value;
}
return null;
}
/**
@@ -152,7 +190,7 @@ public abstract class AnyCache<V> {
* @return false if no memory cache
*/
public boolean putToMemory(String key, V value) {
if (mMemoryCache != null) {
if (mHasMemoryCache) {
mMemoryCache.put(key, value);
return true;
} else {
@@ -168,12 +206,27 @@ public abstract class AnyCache<V> {
* @return false if no disk cache or get error
*/
public boolean putToDisk(String key, V value) {
if (mDiskCache != null) {
if (mHasDiskCache) {
// Wait for pause
waitUntilUnpaused();
String diskKey = hashKeyForDisk(key);
return mDiskCache.put(diskKey, value);
synchronized (mDiskCacheLock) {
while (mDiskCacheStarting) {
try {
mDiskCacheLock.wait();
} catch (InterruptedException e) {
// Just ignore
}
}
if (mDiskCache != null) {
mDiskCache.put(key, value);
return true;
} else {
return false;
}
}
} else {
return false;
}
@@ -186,17 +239,8 @@ public abstract class AnyCache<V> {
* @param value the value
*/
public void put(String key, V value) {
if (mMemoryCache != null) {
mMemoryCache.put(key, value);
}
if (mDiskCache != null) {
// Wait for pause
waitUntilUnpaused();
String diskKey = hashKeyForDisk(key);
mDiskCache.put(diskKey, value);
}
putToMemory(key, value);
putToDisk(key, value);
}
/**
@@ -230,15 +274,54 @@ public abstract class AnyCache<V> {
}
}
/**
* Evicts all of the items from the memory cache
*/
public void clearMemory() {
if (mHasMemoryCache) {
mMemoryCache.evictAll();
}
}
/**
* Clear disk cache
*/
public void clearDisk() {
synchronized (mDiskCacheLock) {
mDiskCacheStarting = true;
if (mDiskCache != null && !mDiskCache.isClosed()) {
try {
mDiskCache.delete();
} catch (IOException e) {
Log.e(TAG, "AnyCache clearCache", e);
}
File cacheDir = mDiskCache.getCacheDir();
int maxSize = mDiskCache.getMaxSize();
mDiskCache = null;
initDiskCache(cacheDir, maxSize);
}
}
}
public void flush() {
synchronized (mDiskCacheLock) {
if (mDiskCache != null) {
try {
mDiskCache.flush();
} catch (IOException e) {
Log.e(TAG, "AnyCache flush", e);
}
}
}
}
/**
* Evicts all of the items from the memory cache and lets the system know
* now would be a good time to garbage collect
*/
public void evictAll() {
if (mMemoryCache != null) {
mMemoryCache.evictAll();
}
System.gc();
public void clear() {
clearMemory();
clearDisk();
}
/**
@@ -278,6 +361,43 @@ public abstract class AnyCache<V> {
return builder.toString();
}
/**
* A holder class that contains cache parameters.
*/
public static class AnyCacheParams {
public boolean hasMemoryCache = false;
public int memoryCacheMaxSize = 0;
public boolean hasDiskCache = false;
public File diskCacheDir = null;
public int diskCacheMaxSize = 0;
/**
* Check AnyCacheParams is valid
*
* @throws IllegalStateException
*/
public void isValid() throws IllegalStateException {
if (!hasMemoryCache && !hasDiskCache) {
throw new IllegalStateException("No memory cache and no disk cache. What can I do for you?");
}
if (hasMemoryCache && memoryCacheMaxSize <= 0) {
throw new IllegalStateException("Memory cache max size must be bigger than 0.");
}
if (hasDiskCache) {
if (diskCacheDir == null) {
throw new IllegalStateException("Disk cache dir can't be null.");
}
if (diskCacheMaxSize <= 0) {
throw new IllegalStateException("Disk cache max size must be bigger than 0.");
}
}
}
}
public class MemoryCahce<E> extends LruCache<String, E> {
public AnyCache<E> mParent;
@@ -298,12 +418,38 @@ public abstract class AnyCache<V> {
private static final int IO_BUFFER_SIZE = 8 * 1024;
public DiskLruCache mDiskLruCache;
public AnyCache<E> mParent;
private DiskLruCache mDiskLruCache;
private AnyCache<E> mParent;
private File mCacheDir;
private int mMaxSize;
public DiskCache(File cacheDir, int size, AnyCache<E> parent) throws IOException {
mDiskLruCache = DiskLruCache.open(cacheDir, 1, 1, size);
mParent = parent;
mCacheDir = cacheDir;
mMaxSize = size;
}
public File getCacheDir() {
return mCacheDir;
}
public int getMaxSize() {
return mMaxSize;
}
public boolean isClosed() {
return mDiskLruCache.isClosed();
}
public void delete() throws IOException {
mDiskLruCache.delete();
}
public void flush() throws IOException {
mDiskLruCache.flush();
}
public E get(String key) {
@@ -347,7 +493,6 @@ public abstract class AnyCache<V> {
final BufferedOutputStream buffOut =
new BufferedOutputStream(os, IO_BUFFER_SIZE);
boolean result = mParent.write(buffOut, value);
mDiskLruCache.flush();
editor.commit();
return result;
} else {
+15 -15
View File
@@ -49,25 +49,25 @@ public class ImageCache extends AnyCache<Bitmap>{
public static @NonNull ImageCache getImageCache(@NonNull Context context) {
if (sImageCache == null) {
sImageCache = new ImageCache(context.getApplicationContext());
final ActivityManager activityManager = (ActivityManager)context
.getSystemService(Context.ACTIVITY_SERVICE);
final int memoryCacheMax = Math.round(MEM_CACHE_DIVIDER * activityManager.getMemoryClass()
* 1024 * 1024);
AnyCacheParams params = new AnyCacheParams();
params.hasMemoryCache = true;
params.memoryCacheMaxSize = memoryCacheMax;
params.hasDiskCache = true;
params.diskCacheDir = getDiskCacheDir(context, TAG);
params.diskCacheMaxSize = 20 * 1024 * 1024;
sImageCache = new ImageCache(params);
}
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);
}
public ImageCache(AnyCacheParams params) {
super(params);
}
@Override
@@ -19,6 +19,7 @@ package com.hippo.ehviewer.ui;
import android.app.Activity;
import com.google.analytics.tracking.android.EasyTracker;
import com.hippo.ehviewer.cache.ImageCache;
import com.hippo.ehviewer.util.Config;
import com.hippo.ehviewer.util.Ui;
@@ -31,6 +32,13 @@ public abstract class AbsActivity extends Activity {
Ui.adjustOrientation(this);
}
@Override
protected void onPause() {
super.onPause();
ImageCache.getImageCache(this).flush();
}
@Override
protected void onStart() {
super.onStart();