61

I am using several SharedPreferences to store data in my app. Some preferences are used in a lot of activites.

I know that the SharedPreferences are internally backed by a map for fast read-access and written to sdcard when settings are changed.

I wonder which way is better if a sharedpreference is accessed by a lot of activies:

  1. Instantiate it in every activity using the activity context.
  2. Instantiate it in every activity, but using the application context.
  3. Put it in e.g. the Application class and instantiate it only once there, similar to a singleton.

If I use 1. solution is there a sharedpreference object for every activity? And will the sharedpreference's internal map get destroyed when the activity is destroyed?

If I use 2. solution will there be only one instance although I call getSharedPreferences in every activity? And will the internal map be in memory as long as the application is alive?

Hopefully someone knows how Android handles it internally.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
d1rk
  • 1,956
  • 2
  • 14
  • 19
  • I would recommend choice three, you can access from all of your activities and you only have to do one read. – Joel Jul 19 '12 at 18:38

4 Answers4

87

It is worth reviewing the sources that show that a Context instance (be it an Activity or an Application instance) share the same static map HashMap<String, SharedPreferencesImpl>.

So whenever you request an instance of SharedPreferences by the same name via Context.getSharedPreferences(name, mode) you get the same instance since it first checks if the map already contains SharedPreferences instance for a key (which is the passed name). Once SharedPreferences instance is loaded it will not be loaded again, but taken from the map instead.

So it actually does not matter which way you go, the important thing is to use the same name in order to get the same prefs from different parts of the application. However creating a single "access point" for the prefs could be a plus. So it could be a singleton wrapper over the prefs instantiated in Application.onCreate().

Vit Khudenko
  • 28,288
  • 10
  • 63
  • 91
25

SharedPreferences are managed internally by Android as singletons. You can get as many instances as you want using:

context.getSharedPreferences(name, mode);

as long as you use the same name, you'll always get the same instance. Therefore there are no concurrency problems.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
11

I will prefer using a singleton class for preference, initialize preference once by application context. create getter and setter(get/put) methods to add, update and delete data.

This way it will create instance once and can be more readable,reusable.

AAnkit
  • 27,299
  • 12
  • 60
  • 71
  • Also it is good when an application returns from HTTP-request. In this case a context (activity) may not exist, so context.getSharedPreferences will lead to NPE. When using a singleton this won't happen. – CoolMind Jan 25 '17 at 16:33
0

We can make a Preferences Singleton Class and make instance of that class in extended Application class with applicationContext, so we may use that object in whole application I have made a sharedPreferenceManager Class and make a static object by providing applicationContext. Now static object can be accessible anywhere in project

public class App extends Application {
    public static App myApp;
    public static PreferenceManagerSignlton preferenceManagerSingleton;
    @Override
    public void onCreate() {
        super.onCreate();
        myApp = this;
        preferenceManagerSingleton = new PreferenceManagerSignlton();
        preferenceSingleton.initialize(getApplicationContext());
    }
}

Accessing static object in project

App.myapp.PreferenceManagerSignltonz.getSavedValue();
Stefano Sansone
  • 2,377
  • 7
  • 20
  • 39