vincentbrison / dualcache Goto Github PK
View Code? Open in Web Editor NEWThis android library provide a cache with 2 layers, one in RAM in top of one disk.
License: Apache License 2.0
This android library provide a cache with 2 layers, one in RAM in top of one disk.
License: Apache License 2.0
Currently, CacheSerializer forces everything to be a String. This can be inefficient for data that is not naturally a String since it requires creating a String just to store the data, particularly if no ram serializer is used. However, DiskLruCache exposes streams that can be used directly to write data. It would be helpful to allow a version of CacheSerializers which can use these streams.
import org.apache.commons.io.IOUtils;
Please remove any dependencies to apache.
Something like
dualCache.containsData();
Add automated testing
Add the possibility to choose custom serializer for RAM Layer and Disk Layer
I got "cannot resolve symbol ObjectMapper error" in JsonSerializer.
can u plz tell me how to resolve it?
DiskLruCache
implements Closeable
which leads me to believe it should be properly closed when it's done.
I see no way of doing that in the DualCache
interface. Shouldn't DualCache
also implement Closeable
to allow for closing the underlying DiskLruCache
?
I use the following to to cache Bitmaps:
DualCacheLogUtils.enableLog();
DualCacheContextUtils.setContext(RadioApplication.getAppContext());
cache = new DualCacheBuilder<Bitmap>(CACHE_NAME, CACHE_VERSION, Bitmap.class)
.useReferenceInRam(CACHE_RAM, new SizeOfBitmap())
.useDefaultSerializerInDisk(CACHE_DISK, true);
Storing seems to work fine, but when trying to retrieve an entry from cache, I get the following:
I/dualcache: Entry for e5429ada18f6df2de9c9870c379b7eb4 is on disk.
E/dualcache: error :
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class android.graphics.Bitmap]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: {"mStackTrace":null,"mBuffer":null,"mRestorePolicyInfo":null,"mFinalizer":["android.graphics.Bitmap$BitmapFinalizer",{"mStackTrace":null,"mIsPreloaded":false,"mNativeBitmap":2140966016,"mPixelsIsAllocated":true,"mRecycled":false,"mBitmapSize":878000}],"mNinePatchChunk":null,"mLayoutBounds":null,"mIsMutable":false,"mIsPreloading":false,"mIsPremultiplied":true,"mIsRestorable":false,"mInUse":false,"mNativeBitmap":2140966016,"mNativeBitmapFreed":false,"mHeight":439,"mPixelsIsAllocated":true,"mRecycled":false,"mDensity":480,"mBitmapSize":878000,"mWidth":500}; line: 1, column: 2]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1063)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:264)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3051)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2146)
at com.vincentbrison.openlibraries.android.dualcache.lib.DualCache.get(DualCache.java:410)
What is the problem??
Is it really possible there is no way to remove from cache. Something like cache.remove(key)?
Example, I call web service to get some object. I want to cache that object (the way of implementing of cache is not important to me). What is important is that when I use web service to update that object I want to invalidate cache. I think it is very common requirement, but cannot find any good library which does this.
It's working perfectly fine in debug mode. But once I try with signed apk having progaurd with minifyEnabled true, it crashes.
I have tried using
-keep class com.vincentbrison.* { ; }
-dontwarn com.vincentbrison.
But no luck yet.
Can anyone tell me how to use this dualcache?
can i use this with jsondata?
dualCache.put(key, object);
logger.debug("put_result: " + "key " + key + "/" + object);
logger.debug("demo_get: " + "key " + key + "/" + dualCache.get(key));
Sometimes dualCache.get(key)
returns null
. Is there any callback or sync way to put object in cache?
hi vincentbrison ,i am tring to generate library using gradle.i installed gradle independently i dont have android studio setup.but when i ma trying to create jar using gradlew.bat got errr Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_
how can i solve it?
for example, i would like to remove the cache content that is not modified for over a month, how can i implement this feature?
Hi,
How to deal this case,I want to put some data like ArrayList<HomeBannerModel>
to DualCache, and get ArrayList<HomeBannerModel>
,but The third parameter type of Build is Class
,not a Type
/**
* Start the building of the cache.
* @param id is the id of the cache (should be unique).
* @param appVersion is the app version of the app. If data are already stored in disk cache
* with previous app version, it will be invalidate.
* @param clazz is the class of object to store in cache.
*/
public Builder(String id, int appVersion, Class<T> clazz) {
this.id = id;
this.appVersion = appVersion;
this.clazz = clazz;
this.ramMode = null;
this.diskMode = null;
this.logEnabled = false;
}
Hi,
I want to cache Bitmap objects.
I have this:
private static final int RAM_MAX_SIZE = 2048;
DualCacheLogUtils.enableLog();
DualCacheContextUtils.setContext(getApplicationContext());
cache = new DualCacheBuilder("bitmapCache", 1, Bitmap.class)
.useDefaultSerializerInRam(RAM_MAX_SIZE)
.noDisk();
And I have DataHolder where I have reference to "cache" instance.
DataHolder.getInstance().setCache(cache);
When I put object to cache:
key = "data1";
cache.put(key, result);
and immediately I try to get this object with:
Bitmap bm = cache.get(key);
bm is equal to null.
Class that implements SizeOf is returning -> object.getHeight() * object.getWidth() * 4
What I'm doing wrong ?
Hey ,
Thanks for the very helpful lib ,
how can i include your license in my app for release
and what is the configurations for proguard
thanks in advance
...on the releases page: https://github.com/vincentbrison/dualcache/releases
After changing the language on my phone, I got following exception:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jakewharton.disklrucache.DiskLruCache$Editor.set(int, java.lang.String)' on a null object reference
at com.vincentbrison.openlibraries.android.dualcache.lib.DualCache.put(DualCache.java:313)
at ...
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)#
at java.lang.Thread.run(Thread.java:818)
Add the possibility to use reference (and an effective way of having a good size of method on the objects pointed by these reference for the RAM layer).
I want to use your library for disk caching some JPG images. I don't see how to do this, I looked at your methods
useCustomSerializerInDisk()
and
useDefaultSerializerInDisk()
both seem to assume I want to store data as Strings, which isn't a very good assumption.
Hi,
When running unit tests with RobolectricGradleTestRunner I get a NoSuchMethodException exception stack trace when invalidating cache:
java.lang.NoSuchMethodException: java.util.LinkedHashMap.eldest()
at java.lang.Class.getMethod(Class.java:1786)
at com.vincentbrison.openlibraries.android.dualcache.RamLruCache.trimToSize(RamLruCache.java:210)
at com.vincentbrison.openlibraries.android.dualcache.ReferenceLruCache.trimToSize(ReferenceLruCache.java:7)
at com.vincentbrison.openlibraries.android.dualcache.RamLruCache.evictAll(RamLruCache.java:316)
at com.vincentbrison.openlibraries.android.dualcache.DualCache.invalidateRAM(DualCache.java:415)
at com.vincentbrison.openlibraries.android.dualcache.DualCache.invalidate(DualCache.java:407)
I guess this is due to difference between Oracle and Dalvik implementation. Maybe an iterator mechanism could be used when calling "eldest()" fails? This could make unit tests outside Android environment work better. What do you think?
Thanks for working on this library! :)
Javadoc for usePrivateFiles params in Builder.useSerializerInDisk() says: "true
if you want to use {@link Context#MODE_PRIVATE} with the default disk cache folder."
But, as far as I see, both folder below refers to the internal storage and Context.MODE_PRIVATE is used by default:
context.getDir(CACHE_FILE_PREFIX + this.id, Context.MODE_PRIVATE)
new File(context.getCacheDir().getPath() + "/" + CACHE_FILE_PREFIX + "/" + this.id)
So, the only difference is the path: later creates folder in the cache
folder, which might be cleaned-up by the system.
I have a sample Activity which tries to add Bitmaps to the cache:
DualCache<Bitmap> mCache;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.activity_main );
CacheSerializer<Bitmap> jsonSerializer = new JsonSerializer<> ( Bitmap.class );
mCache = new Builder<Bitmap> ( CACHE_NAME, TEST_APP_VERSION )
.enableLog ( )
.useSerializerInRam ( RAM_MAX_SIZE, jsonSerializer )
.useSerializerInDisk ( DISK_MAX_SIZE, true, jsonSerializer, getApplicationContext ( ) )
.build ( );
Button put = (Button) findViewById ( R.id.put );
put.setOnClickListener ( new View.OnClickListener ( ) {
@Override
public void onClick(View view) {
Bitmap bm = BitmapFactory.decodeResource ( getResources ( ), R.mipmap.ic_launcher );
mCache.put ( "a", bm );
}
} );
Button get = (Button) findViewById ( R.id.get );
get.setOnClickListener ( new View.OnClickListener ( ) {
@Override
public void onClick(View view) {
Bitmap bitmap = mCache.get ( "a" );
ImageView imv = (ImageView) findViewById ( R.id.imageView );
if (bitmap != null) {
imv.setImageBitmap ( bitmap );
}
}
} );
}
I first press put button (there is no error) and then get. But after pressing get I get this error:
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalStateException
at com.vincentbrison.openlibraries.android.dualcache.JsonSerializer.fromString(JsonSerializer.java:38)
at com.vincentbrison.openlibraries.android.dualcache.DualCache.get(DualCache.java:246)
Add javadocs at least for the public api
Hi, I can use Java's built-in ObjectOutputStream
to serialize my data into a byte array instead of using the heavy JSON. But there might be some byte illegal for String, e.g. '\0' in the middle of the string. Do I have to encode my byte array to something like base64 or can I store the byte array into String directly using charset ISO-8859-1 (8-bit)? Furthermore, I hope byte arrays can be supported directly in interface CacheSerializer
.
I think it would be a nice addition if one could give a maximum TTL when storing an object (default 0 = forever). Then when an object is requested from cache it is only returned if it hasn't expired, yet.
Is there a possibility to flush the ram cache to disk? We need to persist the cached data
Is it dangerous to build multiple DualCache instances with the same id?
Not a bug just a little improvment.
When you try to cache an obect bigger than the DISK_MAX_SIZE you've set, nothing is telling you something is wrong and it simply does nothing.
For my case it was on this part of the put method, the exception was not throw
if (mDiskMode.equals(DualCacheDiskMode.ENABLE_WITH_DEFAULT_SERIALIZER)) {
try {
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
editor.set(0, jsonStringObject);
editor.commit();
} catch (IOException e) {
DualCacheLogUtils.logError(e);
}
}
hello,
now i want to use doublecache.
i prepared all the needed gradle lines and now i want to instantiate the caching service object.
In your description this is the lines to do that:
cache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class)
.enableLog()
.useReferenceInRam(RAM_MAX_SIZE, new SizeOfVehiculeForTesting()
new SizeOfVehiculeForTesting())
.useSerializerInDisk(DISK_MAX_SIZE, true, new DualCacheTest.SerializerForTesting(), getContext())
.build();
but what is the type of cache object ?
what is AbstractVehicule.class means, i try to get it's declaration to understand but i didn't found comments?
what should be the default or recommanded number for RAM_MAX_SIZE, DISK_MAX_SIZE
what is new DualCacheTest.SerializerForTesting(), new SizeOfVehiculeForTesting()
I really don't understand how to use it and i didn't find any tutorials, examples, real codes help?
so please help?
Why do I initialize DualCache complains
This is my initialization code
public void onCreate() {
super.onCreate();
DualCacheLogUtils.enableLog();
DualCacheContextUtils.setContext(getApplicationContext());
DualCache mCache = new DualCacheBuilder(mCacheId, 2, String.class)
.useDefaultSerializerInRam(mRamCacheSize)
.useDefaultSerializerInDisk(mDiskCacheSize, true);
}
This is the error information
java.lang.VerifyError: com/vincentbrison/openlibraries/android/dualcache/lib/DualCache
at com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheBuilder.(DualCacheBuilder.java:18)
at com.jbp.minegold.MinegoldApplication.onCreate(MinegoldApplication.java:31)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1000)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4502)
at android.app.ActivityThread.access$1300(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1336)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5153)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
at dalvik.system.NativeStart.main(Native Method)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.