package quickutils.core.cache; import android.content.Context; import android.os.AsyncTask; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import quickutils.core.QuickUtils; import quickutils.core.cache.interfaces.DeleteFromCacheCallback; import quickutils.core.cache.interfaces.ReadFromCacheCallback; import quickutils.core.cache.interfaces.SaveToCacheCallback; public class GsonCache { private static SimpleDiskCache cache; private static long mMaxSize; private static Context mContext; /** * Initialize * * @param maxSize the maximum size in bytes. */ public static synchronized void init(long maxSize) throws Exception { mContext = QuickUtils.getContext(); mMaxSize = maxSize; cache = SimpleDiskCache.open(mContext.getFilesDir(), 1, mMaxSize); } /** * Check if an object with the given key exists in the Reservoir. * * @param key the key string. * @return true if object with given key exists. */ public static boolean existsKey(String key) throws Exception { return cache.contains(key); } public static void deleteAll() throws Exception { cache.wipeData(); } /** * Put an object into Reservoir with the given key. This a blocking IO operation. Previously * stored object with the same * key (if any) will be overwritten. * * @param key the key string. * @param object the object to be stored. */ public static void save(String key, Object object) throws Exception { String json = new Gson().toJson(object); cache.put(key, json); } /** * Put an object into Reservoir with the given key asynchronously. Previously * stored object with the same * key (if any) will be overwritten. * * @param key the key string. * @param object the object to be stored. * @param callback a callback of type {@link quickutils.core.cache.interfaces.SaveToCacheCallback * .ReservoirPutCallback} which is called upon completion. */ public static void saveAsync(String key, Object object, SaveToCacheCallback callback) { new SaveTask(key, object, callback).execute(); } /** * Get an object from Reservoir with the given key. This a blocking IO operation. * * @param key the key string. * @param classOfT the Class type of the expected return object. * @return the object of the given type if it exists. */ public static <T> T read(String key, Class<T> classOfT) throws Exception { String json = cache.getString(key).getString(); T value = new Gson().fromJson(json, classOfT); if (value == null) { throw new NullPointerException(); } return value; } public static <T> void readAsync(String key, TypeToken typeToken, ReadFromCacheCallback<T> callback) { new LoadTask<T>(key, typeToken.getRawType(), callback).execute(); } /** * Delete an object from Reservoir with the given key. This a blocking IO operation. Previously * stored object with the same * key (if any) will be deleted. * * @param key the key string. */ public static void delete(String key) throws Exception { cache.delete(key); } /** * Delete an object into Reservoir with the given key asynchronously. Previously * stored object with the same * key (if any) will be deleted. * * @param key the key string. * @param callback a callback of type {@link quickutils.core.cache.interfaces.DeleteFromCacheCallback * .ReservoirDeleteCallback} which is called upon completion. */ public static void deleteAsync(String key, DeleteFromCacheCallback callback) { new DeleteTask(key, callback).execute(); } /** * AsyncTask to perform put operation in a background thread. */ private static class SaveTask extends AsyncTask<Void, Void, Void> { private final String key; private Exception e; private final SaveToCacheCallback callback; final Object object; private SaveTask(String key, Object object, SaveToCacheCallback callback) { this.key = key; this.callback = callback; this.object = object; this.e = null; } @Override protected Void doInBackground(Void... params) { try { String json = new Gson().toJson(object); cache.put(key, json); } catch (Exception e) { this.e = e; } return null; } @Override protected void onPostExecute(Void aVoid) { if (callback != null) { if (e == null) { callback.onSuccess(); } else { callback.onFailure(e); } } } } /** * AsyncTask to perform get operation in a background thread. */ private static class LoadTask<T> extends AsyncTask<Void, Void, T> { private final String key; private final ReadFromCacheCallback callback; private final Class<T> classOfT; private Exception e; private LoadTask(String key, Class<T> classOfT, ReadFromCacheCallback callback) { this.key = key; this.callback = callback; this.classOfT = classOfT; this.e = null; } @Override protected T doInBackground(Void... params) { try { String json = cache.getString(key).getString(); T value = new Gson().fromJson(json, classOfT); if (value == null) throw new NullPointerException(); return value; } catch (Exception e) { this.e = e; return null; } } @Override protected void onPostExecute(T object) { if (callback != null) { if (e == null) { callback.onSuccess(object); } else { callback.onFailure(e); } } } } /** * AsyncTask to perform delete operation in a background thread. */ private static class DeleteTask extends AsyncTask<Void, Void, Void> { private final String key; private Exception e; private final DeleteFromCacheCallback callback; private DeleteTask(String key, DeleteFromCacheCallback callback) { this.key = key; this.callback = callback; this.e = null; } @Override protected Void doInBackground(Void... params) { try { cache.delete(key); } catch (Exception e) { this.e = e; } return null; } @Override protected void onPostExecute(Void aVoid) { if (callback != null) { if (e == null) { callback.onSuccess(); } else { callback.onFailure(e); } } } } }