问题
I'm making an android app which uses google cloud endpoints as the backend. So I'm making request from the app. I want to cache the response of these requests in memory as well as storage.
I want to cache the response on the phone, so that I don't have to make unnecessary repeated network requests.
I searched the internet for some inbuilt solution but couldn't find anything like that in the api provided by google.
There's a total of about 2MB data that I want to cache. This data is spread over 20 end point requests.
What are my best options to implement such a cache?
回答1:
You can implement an amazing library called android-easy-cache
the sample implementation is shown in my answer here
回答2:
I'm going to answer my own question so that it can help someone until there's a more clean solution available.
I'm using this library for caching responses: https://github.com/vincentbrison/android-easy-cache
- GCE result is a
GenericJson
. Serialize the response using this SerializationUtil Use this code to create DualCache library boilerplate.
dualCacheByteArray
for caching the response anddualCacheDate
for keeping track oftime_to_live_for_response
public static final int APP_CACHE_VERSION = 1; public static final String CACHE_ID = "cache_id_string"; public static final String CACHE_ID_DATE = "cache_id_date"; public static final int RAM_CACHE_SIZE = 5 * 1024 * 1024; // 5 mb public static final int DISK_CACHE_SIZE = 15 * 1024 * 1024; //15 mb public static final int RAM_CACHE_SIZE_DATE = 1 * 1024 * 1024; // 5 mb public static final int DISK_CACHE_SIZE_DATE = 3 * 1024 * 1024; //15 mb private DualCache<byte[]> dualCacheByteArray; private DualCache<Date> dualCacheDate; public DualCache<byte[]> getDualCacheByteArray() { if (dualCacheByteArray == null) { dualCacheByteArray = new DualCacheBuilder<byte[]>(Constants.CACHE_ID, Constants.APP_CACHE_VERSION, byte[].class) .useReferenceInRam(Constants.RAM_CACHE_SIZE, new SizeOf<byte[]>() { @Override public int sizeOf(byte[] object) { return object.length; } }) .useDefaultSerializerInDisk(Constants.DISK_CACHE_SIZE, true); } return dualCacheByteArray; } public DualCache<Date> getDualCacheDate() { if (dualCache == null) { dualCacheDate = new DualCacheBuilder<Date>(Constants.CACHE_ID_DATE, Constants.APP_CACHE_VERSION, Date.class) .useReferenceInRam(Constants.RAM_CACHE_SIZE_DATE, new SizeOf<Date>() { @Override public int sizeOf(Date date) { byte[] b = new byte[0]; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(date); oos.flush(); byte[] buf = baos.toByteArray(); return buf.length; } catch (IOException e) { Log.e("some prob", "error in calculating date size for caching", e); } return sizeOf(date); } }) .useDefaultSerializerInDisk(Constants.DISK_CACHE_SIZE_DATE, true); } return dualCacheDate; }
Now use the above
DualCache
s to cache your response.getDualCacheByteArray().put(YOUR_RESPONSE_CACHE_KEY, serializedProduct); getDualCacheDate().put(YOUR_RESPONSE_CACHE_KEY, new Date());
Before making a new request using google cloud endpoints, you should check in dual cache if the old response is already present in cache
public byte[] getCachedGenericJsonByteArray(String key, int cacheExpireTimeInMinutes) { Date cachingDate = getDualCacheDate().get(key); if(cachingDate!=null) { long expirationTime = TimeUnit.MILLISECONDS.convert(cacheExpireTimeInMinutes, TimeUnit.MINUTES); long timeElapsedAfterCaching = new Date().getTime() - cachingDate.getTime(); if (timeElapsedAfterCaching >= expirationTime) { //the cached data has expired return null; } else { byte[] cachedGenericJsonByteArray = getDualCacheByteArray().get(key); return cachedGenericJsonByteArray; } } else { //result for this key was never cached or is cleared return null; } }
if the cached byte array is not null, then deserialize it using SerializationUtil and use it as a cached response, else make a new request from google cloud endpoints
EDIT : Using serialization util may not be necessary in every case as pointed out by Sanket Berde in other answer
来源:https://stackoverflow.com/questions/33485491/how-to-cache-the-response-in-google-cloud-endpoint