Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save alphamu/8748537a3b73d9c58b4c to your computer and use it in GitHub Desktop.
Save alphamu/8748537a3b73d9c58b4c to your computer and use it in GitHub Desktop.
A SharedPreferences singleton that can be used to centralise and simplify reading and writing of SharedPerferences in your Android app. There are 2 versions, one that uses static String for Keys and an other that uses enums. Which one you use comes down to your preference, enums I feel provides better control when you have multiple programmers w…
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
import android.content.Context;
import android.content.SharedPreferences;
/*
* A Singleton for managing your SharedPreferences.
*
* You should make sure to change the SETTINGS_NAME to what you want
* and choose the operating made that suits your needs, the default is
* MODE_PRIVATE.
*
* IMPORTANT: The class is not thread safe. It should work fine in most
* circumstances since the write and read operations are fast. However
* if you call edit for bulk updates and do not commit your changes
* there is a possibility of data loss if a background thread has modified
* preferences at the same time.
*
* Usage:
*
* int sampleInt = ${NAME}.getInstance(context).getInt(Key.SAMPLE_INT);
* ${NAME}.getInstance(context).set(Key.SAMPLE_INT, sampleInt);
*
* If ${NAME}.getInstance(Context) has been called once, you can
* simple use ${NAME}.getInstance() to save some precious line space.
*/
public class ${NAME} {
// TODO: CHANGE THIS TO SOMETHING MEANINGFUL
private static final String SETTINGS_NAME = "default_settings";
private static ${NAME} sSharedPrefs;
private SharedPreferences mPref;
private SharedPreferences.Editor mEditor;
private boolean mBulkUpdate = false;
/**
* Enum representing your setting names or key for your setting.
*/
public enum Key {
/* Recommended naming convention:
* ints, floats, doubles, longs:
* SAMPLE_NUM or SAMPLE_COUNT or SAMPLE_INT, SAMPLE_LONG etc.
*
* boolean: IS_SAMPLE, HAS_SAMPLE, CONTAINS_SAMPLE
*
* String: SAMPLE_KEY, SAMPLE_STR or just SAMPLE
*/
SAMPLE_STR,
SAMPLE_INT
}
private ${NAME}(Context context) {
mPref = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
}
public static ${NAME} getInstance(Context context) {
if (sSharedPrefs == null) {
sSharedPrefs = new ${NAME}(context.getApplicationContext());
}
return sSharedPrefs;
}
public static ${NAME} getInstance() {
if (sSharedPrefs != null) {
return sSharedPrefs;
}
//Option 1:
throw new IllegalArgumentException("Should use getInstance(Context) at least once before using this method.");
//Option 2:
// Alternatively, you can create a new instance here
// with something like this:
// getInstance(MyCustomApplication.getAppContext());
}
public void put(Key key, String val) {
doEdit();
mEditor.putString(key.name(), val);
doCommit();
}
public void put(Key key, int val) {
doEdit();
mEditor.putInt(key.name(), val);
doCommit();
}
public void put(Key key, boolean val) {
doEdit();
mEditor.putBoolean(key.name(), val);
doCommit();
}
public void put(Key key, float val) {
doEdit();
mEditor.putFloat(key.name(), val);
doCommit();
}
/**
* Convenience method for storing doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The enum of the preference to store.
* @param val The new value for the preference.
*/
public void put(Key key, double val) {
doEdit();
mEditor.putString(key.name(), String.valueOf(val));
doCommit();
}
public void put(Key key, long val) {
doEdit();
mEditor.putLong(key.name(), val);
doCommit();
}
public String getString(Key key, String defaultValue) {
return mPref.getString(key.name(), defaultValue);
}
public String getString(Key key) {
return mPref.getString(key.name(), null);
}
public int getInt(Key key) {
return mPref.getInt(key.name(), 0);
}
public int getInt(Key key, int defaultValue) {
return mPref.getInt(key.name(), defaultValue);
}
public long getLong(Key key) {
return mPref.getLong(key.name(), 0);
}
public long getLong(Key key, long defaultValue) {
return mPref.getLong(key.name(), defaultValue);
}
public float getFloat(Key key) {
return mPref.getFloat(key.name(), 0);
}
public float getFloat(Key key, float defaultValue) {
return mPref.getFloat(key.name(), defaultValue);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The enum of the preference to fetch.
*/
public double getDouble(Key key) {
return getDouble(key, 0);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The enum of the preference to fetch.
*/
public double getDouble(Key key, double defaultValue) {
try {
return Double.valueOf(mPref.getString(key.name(), String.valueOf(defaultValue)));
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
public boolean getBoolean(Key key, boolean defaultValue) {
return mPref.getBoolean(key.name(), defaultValue);
}
public boolean getBoolean(Key key) {
return mPref.getBoolean(key.name(), false);
}
/**
* Remove keys from SharedPreferences.
*
* @param keys The enum of the key(s) to be removed.
*/
public void remove(Key... keys) {
doEdit();
for (Key key : keys) {
mEditor.remove(key.name());
}
doCommit();
}
/**
* Remove all keys from SharedPreferences.
*/
public void clear() {
doEdit();
mEditor.clear();
doCommit();
}
public void edit() {
mBulkUpdate = true;
mEditor = mPref.edit();
}
public void commit() {
mBulkUpdate = false;
mEditor.commit();
mEditor = null;
}
private void doEdit() {
if (!mBulkUpdate && mEditor == null) {
mEditor = mPref.edit();
}
}
private void doCommit() {
if (!mBulkUpdate && mEditor != null) {
mEditor.commit();
mEditor = null;
}
}
}
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
import android.content.Context;
import android.content.SharedPreferences;
/*
* A Singleton for managing your SharedPreferences.
*
* You should make sure to change the SETTINGS_NAME to what you want
* and choose the operating made that suits your needs, the default is
* MODE_PRIVATE.
*
* IMPORTANT: The class is not thread safe. It should work fine in most
* circumstances since the write and read operations are fast. However
* if you call edit for bulk updates and do not commit your changes
* there is a possibility of data loss if a background thread has modified
* preferences at the same time.
*
* Usage:
*
* int sampleInt = ${NAME}.getInstance(context).getInt(Key.SAMPLE_INT);
* ${NAME}.getInstance(context).set(Key.SAMPLE_INT, sampleInt);
*
* If ${NAME}.getInstance(Context) has been called once, you can
* simple use ${NAME}.getInstance() to save some precious line space.
*/
public class ${NAME} {
// TODO: CHANGE THIS TO SOMETHING MEANINGFUL
private static final String SETTINGS_NAME = "default_settings";
private static ${NAME} sSharedPrefs;
private SharedPreferences mPref;
private SharedPreferences.Editor mEditor;
private boolean mBulkUpdate = false;
/**
* Class for keeping all the keys used for shared preferences in one place.
*/
public static class Key {
/* Recommended naming convention:
* ints, floats, doubles, longs:
* SAMPLE_NUM or SAMPLE_COUNT or SAMPLE_INT, SAMPLE_LONG etc.
*
* boolean: IS_SAMPLE, HAS_SAMPLE, CONTAINS_SAMPLE
*
* String: SAMPLE_KEY, SAMPLE_STR or just SAMPLE
*/
public static final String SAMPLE_INT = "a_sample_key";
}
private ${NAME}(Context context) {
mPref = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
}
public static ${NAME} getInstance(Context context) {
if (sSharedPrefs == null) {
sSharedPrefs = new ${NAME}(context.getApplicationContext());
}
return sSharedPrefs;
}
public static ${NAME} getInstance() {
if (sSharedPrefs != null) {
return sSharedPrefs;
}
//Option 1:
throw new IllegalArgumentException("Should use getInstance(Context) at least once before using this method.");
//Option 2:
// Alternatively, you can create a new instance here
// with something like this:
// getInstance(MyCustomApplication.getAppContext());
}
public void put(String key, String val) {
doEdit();
mEditor.putString(key, val);
doCommit();
}
public void put(String key, int val) {
doEdit();
mEditor.putInt(key, val);
doCommit();
}
public void put(String key, boolean val) {
doEdit();
mEditor.putBoolean(key, val);
doCommit();
}
public void put(String key, float val) {
doEdit();
mEditor.putFloat(key, val);
doCommit();
}
/**
* Convenience method for storing doubles.
*
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to store.
* @param val The new value for the preference.
*/
public void put(String key, double val) {
doEdit();
mEditor.putString(key, String.valueOf(val));
doCommit();
}
public void put(String key, long val) {
doEdit();
mEditor.putLong(key, val);
doCommit();
}
public String getString(String key, String defaultValue) {
return mPref.getString(key, defaultValue);
}
public String getString(String key) {
return mPref.getString(key, null);
}
public int getInt(String key) {
return mPref.getInt(key, 0);
}
public int getInt(String key, int defaultValue) {
return mPref.getInt(key, defaultValue);
}
public long getLong(String key) {
return mPref.getLong(key, 0);
}
public long getLong(String key, long defaultValue) {
return mPref.getLong(key, defaultValue);
}
public float getFloat(String key) {
return mPref.getFloat(key, 0);
}
public float getFloat(String key, float defaultValue) {
return mPref.getFloat(key, defaultValue);
}
/**
* Convenience method for retrieving doubles.
*
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to fetch.
*/
public double getDouble(String key) {
return getDouble(key, 0);
}
/**
* Convenience method for retrieving doubles.
*
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to fetch.
*/
public double getDouble(String key, double defaultValue) {
try {
return Double.valueOf(mPref.getString(key, String.valueOf(defaultValue)));
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
public boolean getBoolean(String key, boolean defaultValue) {
return mPref.getBoolean(key, defaultValue);
}
public boolean getBoolean(String key) {
return mPref.getBoolean(key, false);
}
/**
* Remove keys from SharedPreferences.
*
* @param keys The name of the key(s) to be removed.
*/
public void remove(String ... keys) {
doEdit();
for (String key : keys) {
mEditor.remove(key);
}
doCommit();
}
/**
* Remove all keys from SharedPreferences.
*/
public void clear() {
doEdit();
mEditor.clear();
doCommit();
}
public void edit() {
mBulkUpdate = true;
mEditor = mPref.edit();
}
public void commit() {
mBulkUpdate = false;
mEditor.commit();
mEditor = null;
}
private void doEdit() {
if (!mBulkUpdate && mEditor == null) {
mEditor = mPref.edit();
}
}
private void doCommit() {
if (!mBulkUpdate && mEditor != null) {
mEditor.commit();
mEditor = null;
}
}
}
import android.content.Context;
import android.content.SharedPreferences;
/*
* A Singleton for managing your SharedPreferences.
*
* You should make sure to change the SETTINGS_NAME to what you want
* and choose the operating made that suits your needs, the default is
* MODE_PRIVATE.
*
* IMPORTANT: The class is not thread safe. It should work fine in most
* circumstances since the write and read operations are fast. However
* if you call edit for bulk updates and do not commit your changes
* there is a possibility of data loss if a background thread has modified
* preferences at the same time.
*
* Usage:
*
* int sampleInt = AppPreferencesEnumExample.getInstance(context).getInt(Key.SAMPLE_INT);
* AppPreferencesEnumExample.getInstance(context).set(Key.SAMPLE_INT, sampleInt);
*
* If AppPreferencesEnumExample.getInstance(Context) has been called once, you can
* simple use AppPreferencesEnumExample.getInstance() to save some precious line space.
*/
public class AppPreferencesEnumExample {
// TODO: CHANGE THIS TO SOMETHING MEANINGFUL
private static final String SETTINGS_NAME = "default_settings";
private static AppPreferencesEnumExample sSharedPrefs;
private SharedPreferences mPref;
private SharedPreferences.Editor mEditor;
private boolean mBulkUpdate = false;
/**
* Enum representing your setting names or key for your setting.
*/
public enum Key {
/* Recommended naming convention:
* ints, floats, doubles, longs:
* SAMPLE_NUM or SAMPLE_COUNT or SAMPLE_INT, SAMPLE_LONG etc.
*
* boolean: IS_SAMPLE, HAS_SAMPLE, CONTAINS_SAMPLE
*
* String: SAMPLE_KEY, SAMPLE_STR or just SAMPLE
*/
SAMPLE_STR,
SAMPLE_INT
}
private AppPreferencesEnumExample(Context context) {
mPref = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
}
public static AppPreferencesEnumExample getInstance(Context context) {
if (sSharedPrefs == null) {
sSharedPrefs = new AppPreferencesEnumExample(context.getApplicationContext());
}
return sSharedPrefs;
}
public static AppPreferencesEnumExample getInstance() {
if (sSharedPrefs != null) {
return sSharedPrefs;
}
//Option 1:
throw new IllegalArgumentException("Should use getInstance(Context) at least once before using this method.");
//Option 2:
// Alternatively, you can create a new instance here
// with something like this:
// getInstance(MyCustomApplication.getAppContext());
}
public void put(Key key, String val) {
doEdit();
mEditor.putString(key.name(), val);
doCommit();
}
public void put(Key key, int val) {
doEdit();
mEditor.putInt(key.name(), val);
doCommit();
}
public void put(Key key, boolean val) {
doEdit();
mEditor.putBoolean(key.name(), val);
doCommit();
}
public void put(Key key, float val) {
doEdit();
mEditor.putFloat(key.name(), val);
doCommit();
}
/**
* Convenience method for storing doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The enum of the preference to store.
* @param val The new value for the preference.
*/
public void put(Key key, double val) {
doEdit();
mEditor.putString(key.name(), String.valueOf(val));
doCommit();
}
public void put(Key key, long val) {
doEdit();
mEditor.putLong(key.name(), val);
doCommit();
}
public String getString(Key key, String defaultValue) {
return mPref.getString(key.name(), defaultValue);
}
public String getString(Key key) {
return mPref.getString(key.name(), null);
}
public int getInt(Key key) {
return mPref.getInt(key.name(), 0);
}
public int getInt(Key key, int defaultValue) {
return mPref.getInt(key.name(), defaultValue);
}
public long getLong(Key key) {
return mPref.getLong(key.name(), 0);
}
public long getLong(Key key, long defaultValue) {
return mPref.getLong(key.name(), defaultValue);
}
public float getFloat(Key key) {
return mPref.getFloat(key.name(), 0);
}
public float getFloat(Key key, float defaultValue) {
return mPref.getFloat(key.name(), defaultValue);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The enum of the preference to fetch.
*/
public double getDouble(Key key) {
return getDouble(key, 0);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The enum of the preference to fetch.
*/
public double getDouble(Key key, double defaultValue) {
try {
return Double.valueOf(mPref.getString(key.name(), String.valueOf(defaultValue)));
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
public boolean getBoolean(Key key, boolean defaultValue) {
return mPref.getBoolean(key.name(), defaultValue);
}
public boolean getBoolean(Key key) {
return mPref.getBoolean(key.name(), false);
}
/**
* Remove keys from SharedPreferences.
*
* @param keys The enum of the key(s) to be removed.
*/
public void remove(Key... keys) {
doEdit();
for (Key key : keys) {
mEditor.remove(key.name());
}
doCommit();
}
/**
* Remove all keys from SharedPreferences.
*/
public void clear() {
doEdit();
mEditor.clear();
doCommit();
}
public void edit() {
mBulkUpdate = true;
mEditor = mPref.edit();
}
public void commit() {
mBulkUpdate = false;
mEditor.commit();
mEditor = null;
}
private void doEdit() {
if (!mBulkUpdate && mEditor == null) {
mEditor = mPref.edit();
}
}
private void doCommit() {
if (!mBulkUpdate && mEditor != null) {
mEditor.commit();
mEditor = null;
}
}
}
import android.content.Context;
import android.content.SharedPreferences;
/*
* A Singleton for managing your SharedPreferences.
*
* You should make sure to change the SETTINGS_NAME to what you want
* and choose the operating made that suits your needs, the default is
* MODE_PRIVATE.
*
* IMPORTANT: The class is not thread safe. It should work fine in most
* circumstances since the write and read operations are fast. However
* if you call edit for bulk updates and do not commit your changes
* there is a possibility of data loss if a background thread has modified
* preferences at the same time.
*
* Usage:
*
* int sampleInt = AppPreferences.getInstance(context).getInt(Key.SAMPLE);
* AppPreferences.getInstance(context).set(Key.SAMPLE, sampleInt);
*
* If AppPreferences.getInstance(Context) has been called once, you can
* simple use AppPreferences.getInstance() to save some precious line space.
*/
public class AppPreferencesStringExample {
// TODO: CHANGE THIS TO SOMETHING MEANINGFUL
private static final String SETTINGS_NAME = "default_settings";
private static AppPreferencesStringExample sSharedPrefs;
private SharedPreferences mPref;
private SharedPreferences.Editor mEditor;
private boolean mBulkUpdate = false;
/**
* Class for keeping all the keys used for shared preferences in one place.
*/
public static class Key {
public static final String SAMPLE = "a_sample_key";
}
private AppPreferencesStringExample(Context context) {
mPref = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
}
public static AppPreferencesStringExample getInstance(Context context) {
if (sSharedPrefs == null) {
sSharedPrefs = new AppPreferencesStringExample(context.getApplicationContext());
}
return sSharedPrefs;
}
public static AppPreferencesStringExample getInstance() {
if (sSharedPrefs != null) {
return sSharedPrefs;
}
//Option 1:
throw new IllegalArgumentException("Should use getInstance(Context) at least once before using this method.");
//Option 2:
// Alternatively, you can create a new instance here
// with something like this:
// getInstance(MyCustomApplication.getAppContext());
}
public void put(String key, String val) {
doEdit();
mEditor.putString(key, val);
doCommit();
}
public void put(String key, int val) {
doEdit();
mEditor.putInt(key, val);
doCommit();
}
public void put(String key, boolean val) {
doEdit();
mEditor.putBoolean(key, val);
doCommit();
}
public void put(String key, float val) {
doEdit();
mEditor.putFloat(key, val);
doCommit();
}
/**
* Convenience method for storing doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to store.
* @param val The new value for the preference.
*/
public void put(String key, double val) {
doEdit();
mEditor.putString(key, String.valueOf(val));
doCommit();
}
public void put(String key, long val) {
doEdit();
mEditor.putLong(key, val);
doCommit();
}
public String getString(String key, String defaultValue) {
return mPref.getString(key, defaultValue);
}
public String getString(String key) {
return mPref.getString(key, null);
}
public int getInt(String key) {
return mPref.getInt(key, 0);
}
public int getInt(String key, int defaultValue) {
return mPref.getInt(key, defaultValue);
}
public long getLong(String key) {
return mPref.getLong(key, 0);
}
public long getLong(String key, long defaultValue) {
return mPref.getLong(key, defaultValue);
}
public float getFloat(String key) {
return mPref.getFloat(key, 0);
}
public float getFloat(String key, float defaultValue) {
return mPref.getFloat(key, defaultValue);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to fetch.
*/
public double getDouble(String key) {
return getDouble(key, 0);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to fetch.
*/
public double getDouble(String key, double defaultValue) {
try {
return Double.valueOf(mPref.getString(key, String.valueOf(defaultValue)));
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
public boolean getBoolean(String key, boolean defaultValue) {
return mPref.getBoolean(key, defaultValue);
}
public boolean getBoolean(String key) {
return mPref.getBoolean(key, false);
}
/**
* Remove keys from SharedPreferences.
*
* @param keys The name of the key(s) to be removed.
*/
public void remove(String... keys) {
doEdit();
for (String key : keys) {
mEditor.remove(key);
}
doCommit();
}
/**
* Remove all keys from SharedPreferences.
*/
public void clear() {
doEdit();
mEditor.clear();
doCommit();
}
public void edit() {
mBulkUpdate = true;
mEditor = mPref.edit();
}
public void commit() {
mBulkUpdate = false;
mEditor.commit();
mEditor = null;
}
private void doEdit() {
if (!mBulkUpdate && mEditor == null) {
mEditor = mPref.edit();
}
}
private void doCommit() {
if (!mBulkUpdate && mEditor != null) {
mEditor.commit();
mEditor = null;
}
}
}
@alphamu
Copy link
Author

alphamu commented Jul 29, 2015

Changed the set() methods to put() to be more consistent with SharedPreferences api

@arvi
Copy link

arvi commented Nov 24, 2016

@alphamu Hello, I'm new to android development and seeing others use apply instead of commit. I'm curious... why use commit when apply is asynchronous? Can I safely replace mEditor.commit() with mEditor.apply() on this code?

Thanks a lot for your guidance. 😄

@NLLAPPS
Copy link

NLLAPPS commented Jan 30, 2018

Is this safe with proguard?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment