DEV Community

Cover image for Gain flexibility with generic shared preferences for Android
Ali Alp
Ali Alp

Posted on • Edited on

Gain flexibility with generic shared preferences for Android

If you have landed here, you have been exposed to the hardship of keeping the Shared Preferences of Android inline. This article will demonstrate a practical method of abstracting all the possible read and write methods for Shared Preference into a simple generic class.

Background

Basically, Shared Preference is a XML file which is acting as a small storage mean for the user’s preferences(settings). while developing an Android application, there are plenty of features or settings which are tightly bounded to the user’s taste, like the colors, themes,fonts,ringtones and etc therefore these preferences need to be saved somewhere to be retrieved on the next execution of the application and that is when the need for a small storage comes to the surface. Android has offered a simple mechanism to achieve the storage of the user’s preferences by introducing the Shared Preferences library.

A simple storage of a setting like the background color goes like this

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(applicationContext);
SharedPreferences.Editor editor = sp.edit();
editor.putString("background_color", "green");
editor.apply();
Enter fullscreen mode Exit fullscreen mode

Then Android will save it in /data/data/YOUR_APP_PACKAGE_NAME/shared_prefs/YOUR_APP_PACKAGE_NAME_preferences.xml like this

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="background_color">green</string>
</map>
Enter fullscreen mode Exit fullscreen mode

and later the value of the “background_color” can be retrieved from the Shared Preferences like this

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(applicationContext);
String defaultValue="white";
String Value = sp.getString("background_color", defaultValue);
Issue
Enter fullscreen mode Exit fullscreen mode

As it can be seen above for storing the string value in the shared preferences, the putString method needs to be called as well as getString method for retrieving it. Seems pretty straight forward till the application begins to grow and the number of the preferences which it requires to store increase with it.

On the other hand, for storing Boolean, putBooean()/getBoolean() needs to be called innorder to store and retrieve of the preferences respectively.

Solution

The first solution which will pop up is to use a static helper class to take care of this operation, therefore for retrieving/storing String values from and to shared preferences something like the code below will be required

private static String getPrefString(Context context,String prefName,String defaultValue){
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
    String ret = sp.getString(prefName, defaultValue);
    return ret;
}

private static void setPrefString(Context context,String prefName,String value){
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = sp.edit();
    editor.putString(prefName, value);
    editor.apply();
}
Enter fullscreen mode Exit fullscreen mode

Furthermore for Boolean, StringSet, Float, Long and Integer, two methods each will be required as well (totally 12 methods) in order to be able to handle the storage/retrieval of all the possible types which one can call it is messy and unnecessary.

Another solution is to make the use of Generics like the code below

And it can be consumed for storing data as follows

new PrefManager<String>(applicationContext).set("background_color","green");
Enter fullscreen mode Exit fullscreen mode

and for retrieving it as follows

new PrefManager<String>(applicationContext).get("background_color","white");
Enter fullscreen mode Exit fullscreen mode

As it can be seen with only two methods all the possible data types are being handled moreover the usage is clean,practical and self explanatory. I hope you have found this way of storing/retrieving data from/to shared preferences useful as much as I did :)

Top comments (2)

Collapse
 
devit951 profile image
Ildarov

I have some questions:
1) What do you expect from the method public void set(String key, T value) if I invoke with this argument set("someKey", new Object()), yes then nothing happens, but it is the wrong approach.
If I create this method, I would throw an IllegalArgumentException("This " + value + " doesn't exist, please specify it.") in the last else statement.

2)The same question to the method public T get(String key, T defaultValue). And in this method would be better instead of return null, there should be throw IllegalStateException("The "+ defaultValue + " with key " + key + " doesn't exist"

Collapse
 
alialp profile image
Ali Alp

First of all you are absolutely right :)
The reason that I haven't included the Exception handling was to transfer the idea of using the generic in shared preferences not the whole implementation but thanks to your comment I have included the Exception handling as well and now it looks like much more complete :)