Linxy Linxy - 1 month ago 20
Android Question

Safest way to use SharedPreferences

I need a class which handles my SharedPreferences and I came up with 3 ways of doing it, however after some research it seems most of them are considered "anti-patterns".

Type 1

public final class MyPrefs {

private MyPrefs(){ throw new AssertionError(); }

public static void setFavoriteColor(Context context, String value){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putString("color_key", value).apply();
}

public static void setFavoriteAnimal(Context context, String value){
// ...
}

// ...

}

/* Usage */
MyPrefs.setFavoriteColor(this, "yellow");


Type 2

public class MyPrefs {

private SharedPreferences mPreferences;
private static MyPrefs INSTANCE;

public static MyPrefs getInstance(Context context){
if(INSTANCE==null){
return new MyPrefs(context);
}
return INSTANCE;
}

private MyPrefs(Context context){
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
}

public void setFavoriteColor(String value){
mPreferences.edit().putString("color_key", value).apply();
}

public void setFavoriteAnimal(Context context, String value){
// ...
}

// ...

}

/* Usage */
MyPrefs myPrefs = MyPrefs.getInstance(this);
myPrefs.setFavoriteColor("red");


Type 3

public class MyPrefs {

SharedPreferences mPreferences;

public MyPrefs(Context context){
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
}

public void setFavoriteColor(String value){
mPreferences.edit().putString("color_key", value).apply();
}

public void setFavoriteAnimal(Context context, String value){
// ...
}

// ...

}

/* Usage */
MyPrefs myPrefs = new MyPrefs(this);
myPrefs.setFavoriteColor("green");


Now my preference wrappers obviously don't consist of only 2 setters, they have lots of getters and setters which do some side processing before saving values, so having the preferences saved and processed within the main activity would cause for a lot of messy code and bugs.

Now which of these approaches will not have a negative impact on performance/cause unexpected bugs?

Answer

Every type is safe, if you used it safely . Please follow the below points and some limitations of every type .

Type 1:-

In the type 1, You directly use this class method, this one is best.

Type 2:-

In the type 2, there is one Static Variable that will cause the MemoryLeakException in your application . If you wanted to use the type 2 than , you have make INSTANCE variable null whenever you use this class (these can solve the problem of MemoryLeakException).

Type 3:-

In the type 3, You have to create Heap Memory(take Ram memory for Instance until its scope end) Or new Instance of class, whenever you want to use this class. This class will help if you have to use this class methods in many time in single Activity.

use this class for simple use of SharePrefernce .....

public class Utility {

    public static boolean getBoolean(Context context, String key) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getBoolean(key, false);
    }

    public static String getString(Context context, String key) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(key, "");
    }

    public static int getInt(Context context, String key) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getInt(key, -1);
    }


    public static void setString(Context context, String key, String value) {
        PreferenceManager.getDefaultSharedPreferences(context).edit().putString(key, value).commit();
    }

    public static void setBoolean(Context context, String key, boolean value) {
        PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(key, value).commit();
    }


}

for setting string ....

Utility.setString(this,"token","your token");

and for getting string ....

Utility.getString(this,"token");

Note :- In this class you don't have to create any Heap Memory OR Static Variable