Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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");

// Reason why it might be considered "Bad"
// Class is not OO, just collection of static methods. "Utility Class"

Type 2

public class MyPrefs {

  private SharedPreferences mPreferences;
  private static volatile MyPrefs sInstance; 

  public static MyPrefs getInstance(Context context){
    if(sInstance == null){
      synchronized(MyPrefs.class){
        if(sInstance == null){
          sInstance = new MyPrefs(context);
        }
      }
    }
    return sInstance;
  }

  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");


// Reason why it might be considered "Bad"
// Singleton's are frowned upon especially
// in android because they can cause problems and unexpected bugs.

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");

// Reason why it might be considered "Bad"
// Lots of boilerplate and must create object every 
// time you want to save a preference.

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?

like image 653
Linxy Avatar asked Oct 14 '16 09:10

Linxy


People also ask

Is shared preference safe?

No for its not safe or no for it is not possible to get these datas. With a simple rooted device, You can read all shared preferences.....

Is SharedPreferences secure Android?

No. It can be easily hacked. If you want to put any sensitive data in shared prefrence file you can encrypt the data and store. You can store your encryption key in NDK/server.

Is SharedPreferences thread safe?

The SharedPreferences implementation in Android is thread-safe but not process-safe. Normally your app will run all in the same process, but it's possible for you to configure it in the AndroidManifest. xml so, say, the service runs in a separate process than, say, the activity.


2 Answers

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 then, you have made INSTANCE variable null whenever you use this class (these can solve the problem of MemoryLeakException).......

Type 3:-

In 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 clas, you don't have to create any Heap Memory OR Static Variable.

like image 97
sushildlh Avatar answered Sep 21 '22 08:09

sushildlh


Include this class in your project and whenever you want to set something in SharedPreferences then use the function with the help of class name and pass parameters. Your task will be easy and you just need to write a single line of code to save and get any value from Shared PReference.

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class SharedPrefManager {

    public static SharedPreferences getSharedPref(Context mContext) {
        SharedPreferences pref = mContext.getSharedPreferences(Constants.SETTINGS, Context.MODE_PRIVATE);

        return pref;
    }

    public static void setPrefVal(Context mContext, String key, String value) {
        if(key!=null){
        Editor edit = getSharedPref(mContext).edit();
        edit.putString(key, value);
        edit.commit();
        }
    }

    public static void setIntPrefVal(Context mContext, String key, int value) {
        if(key!=null){
            Editor edit = getSharedPref(mContext).edit();
            edit.putInt(key, value);
            edit.commit();
        }
    }

    public static void setLongPrefVal(Context mContext, String key, Long value) {
        if(key!=null){
            Editor edit = getSharedPref(mContext).edit();
            edit.putLong(key, value);
            edit.commit();
        }
    }

    public static void setBooleanPrefVal(Context mContext, String key, boolean value) {
        if(key!=null){
            Editor edit = getSharedPref(mContext).edit();
            edit.putBoolean(key, value);
            edit.commit();
        }
    }


    public static String getPrefVal(Context mContext, String key) {
        SharedPreferences pref = getSharedPref(mContext);
        String val = "";
        try {
            if (pref.contains(key))
                val = pref.getString(key, "");
            else
                val = "";
        }catch (Exception e){
            e.printStackTrace();
        }
        return val;
    }

    public static int getIntPrefVal(Context mContext, String key) {
        SharedPreferences pref = getSharedPref(mContext);
        int val = 0;
        try {
        if(pref.contains(key)) val = pref.getInt(key, 0);
        }catch (Exception e){
            e.printStackTrace();
        }
        return val;
    }

    public static Long getLongPrefVal(Context mContext, String key) {
        SharedPreferences pref = getSharedPref(mContext);
        Long val = null;
        try{
        if(pref.contains(key)) val = pref.getLong(key, 0);
    }catch (Exception e){
        e.printStackTrace();
    }
        return val;
    }

    public static boolean getBooleanPrefVal(Context mContext, String key) {
        SharedPreferences pref = getSharedPref(mContext);
        boolean val = false;
        try{
        if(pref.contains(key)) val = pref.getBoolean(key, false);

        }catch (Exception e){
            e.printStackTrace();
        }
        return val;
    }


    public static boolean containkey(Context mContext,String key)
    {
        SharedPreferences pref = getSharedPref(mContext);
        return pref.contains(key);
    } 


}
like image 31
Preetika Kaur Avatar answered Sep 18 '22 08:09

Preetika Kaur