11

I am thinking about how to ideally implement a cache layer in my Android app.

Currently I have generic Activities which display data coming from a remote server. The data is represented by a DTO TemplateInstance. Each TemplateInstance has a Map with Components in it and each of the components can have child components. The components themselves can be Text (String), Image (ByteArray) or Time (or whatever by sub-classing Component).

Currently my app loads a TemplateInstance from the server each time an Activity is started.

I would now like to implement a cache layer in the app, so that

  1. the time to display data is reduced to a minimum,
  2. the data is refreshed when it is changed on the server.

My strategy for this looks like this:

  • The started Activity loads the TemplateInstance from a local storage by an ID (if exists)
  • A UpdateService checks in the background if the TemplateInstance has changed on the server (using a version field in the database)
  • If the server version is greater than the local one or there is no local TemplateInstance then retrieve the data from the server, update the local store and update the view

I implemented this already successfully with db4o. There are just two problems with this solution:

  • db4o is under GPL (I cannot use it)
  • db4o is really slow when I load TemplateInstances which have many images (4 seconds for a query)

Now I am looking for the best replacement for db4o. My ideas about that are until now:

  • SQLite is not suitable because of the structure of the data
  • I don´t need database functionality - retrieving objects by ID would be enough
  • Holding the objects in memory would be significantly faster
  • The memory state should be saved to disk when application exits, so the objects can be reinstantiated at startup

What do you think is the best solution for this?

My research on this brought me to EHCache and JCS, which I have never used. Do you think they are appropriate, also in respect of resources on an Android phone? Or do you have other suggestions?

Konsumierer
  • 1,295
  • 1
  • 15
  • 33

3 Answers3

5

If I understand your situation correctly, I think you should implement your own caching solution.

I would use an HashMap<id, TemplateInstance>. The HashMap is serializable and you could store/load it using ObjectOutputStream and ObjectInputStream, respectively.

goncalossilva
  • 1,830
  • 15
  • 25
  • Thanks! That´s a very neat idea. I ended up building a data structure with several HashMaps and ArrayLists and save this one cache object with ObjectOutputStream. Works like a charm! – Konsumierer Feb 03 '11 at 09:43
  • Unfortunately, it turned out that the solution is not the best, when there is a lot of data to cache like images, because there is a VM limit of how much memory one application can use. – Konsumierer Apr 06 '11 at 14:53
  • 4
    You should use files to cache images, not serializable objects. – goncalossilva Nov 21 '11 at 20:06
2

db4o is not limited to GPL, via its dOCL you can opt for other open source licenses and, if you can't go open source at all, it's also totally free for Android apps

German
  • 10,263
  • 4
  • 40
  • 56
0

You can use my fork of simple-disk-cache This is an easy to use disk cache which uses DiskLruCache under the hood.

I have replace Apache Commons IO dependence with google guava. And have add new public methods: put(String key, String value, Object[] array) - the value I have use to put the timestamp for max TTL (after this time in ms the cache expired) and: T getArray(String key, Class type)

You can put array from Serializable objects like this:

cache.put("key", String.valueOf(new Date().getTime() + 60000), Groups[] arrayGroups);

and get it: Groups[] cacheArray = getCacheArray("key", Groups[].class);

you can put in cache Bitmap images too.

sytolk
  • 7,223
  • 3
  • 25
  • 38