I want to have my application preferences accessible in every activity. I don't want to have to get all of the SharedPreferences in every activity. but instead get SharedPreferences once, and have a global object that has values for all these preferences, like if (AppSettings.isSoundOn()) {// do stuff} and have that object available everywhere with no ifs and buts.
I tried using static classes but you can't get Shared Preferences from a static class. Also it looks like that the class you get SharedPreferences in has to extend Activity, or it produces an error.
I'm sure there is a stupidly simple way this is usually done, as it is basic app functionality, but none of the Android development books I have actually covers how to deal with application wide preferences, and any tutorials I could find just cover setting and getting SharedPreferences which is simple, but you have to do it in every activity.
Create a class like MyApplication and extends from android.app.Application.
In there you can access the sharedpreferences.
In every Activity you can get the Application by using MyApplication app = (MyApplication)this.getApplication();
In MyApplication put a public method that gets the Sharedpreference and one that stores it.
Related
Tried to search but didn't find a satisfying answer to my question, although it seems a bit trivial.
My app has settings the user can modify. My main activity uses these settings all the time, for example, which image to pop-up on certain events, sound/mute and so on. The settings are saved using SharedPreference.
What would be the best (efficient) way to access these settings? I'm familiar with two options:
Read it every time I need it from the SharedPreference instance using getInt, getString or getBoolean.
By SharedPreference instance I mean the one I set during main activity onCreate:
mSharedPref = PreferenceManager.getDefaultSharedPreferences(this);
Hold class members on main activity and update them when the user changes the settings, using:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
I have read through similar questions but have not found the best solution yet. So for example, I load user data from server on application startup. The info is later used in many application components. I do not feel comfortable storing it in singleton (for example, in Application) and make it globally acceptable. The other options I could think of is storing it in shared preferences as JSON or storing it in database. But these approaches might cause some performance hits. How do you solve this common problem?
It seems the best approach is to extend the Application class and add your global variables in, the other Stack Overflow question below could help:
Android Global Variable
Also, if you have a look to the javadoc of Application class it says clear for global application state use.
Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created.
See the full Javadoc here
If you want to access data for all the activities, you can try making a base activity that extends activity and then using base activity as your base class for your other activities
public class MainActivity extends BaseActivity
Then for the BaseActivity
public class BaseActivity extends Activity
In the BaseActivity, store all your values as global variables, these variables can then be passed by each activity that extended base activity
I think you should use Shared Preferences to make the data available throughout you app. Alternativly, you could store your data on internal memory or cache. Depends on the amount of data, depends if you want it to be available between session.
Please read http://developer.android.com/guide/topics/data/data-storage.html for an overview of your options.
I try to use SharedPreferences, but I don't understand why we need the context.
If I create a SharedPreferences with the context of my main activity, can I get something with another context?
For example with an intentService class
Thanks
An IntentService is a subclass of Context (just as are Activity, Application, and many other Android classes). So of course you can create a SharedPreferences from an IntentService. It will see the same SharedPreferences values that any Activity or other Context in your application would see. (That's why it's called shared.) You just have to make sure that you apply() or commit() changes made in the preference's editor in one context for the changes to be seen in other places. This is all covered in the docs.
The SharedPreferences are read and saved to disk.
Therefore the class needs to know where the app is located - and the only way to know that is thru a Context.
In standard Java there are global (static) objects, so you can do like for example System.getProperty("user.home") to access the user's home directory. That systems isnt maintained in Android - in Android you need to use the Context to get to the home dir of the app
Yes, This is non sense question,but anyway.
As you know about SharedPreference.It is used to Store private primitive data.
Here,on private data term. This means this data is stored to your application's storage path. Which is data/data/yourpackageName/shared_prefs.
So To access your application's storage, SharePreference needs your active context of any running Activity.
Looking at the Android Source Code. You would get to know that Context class internally maintains a static HashMap of shared preferences for quick access:
private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
new HashMap<String, SharedPreferencesImpl>();
So you can get SharedPreferences from any class like Intent Service or Activity etc which extends Context and it will always return the same object if given the same name.
Note: IntentService does extend Context if you trace the chain:
IntentService extends Service
Service extends ContextWrapper
ContextWrapper extends Context
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:
Instantiate it in every activity using the activity context.
Instantiate it in every activity, but using the application context.
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.
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().
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.
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.
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();
I have a Login Activity which stores credentials in its own SharedPreferences; then I added two getters for reading them, something like
public String getUsername() {
return getPreferences(MODE_PRIVATE).getString("#username", null);
}
but this throws a NPE when I call it like this
String mUser = (new Login()).getUsername();
It seems that the Activity cannot read its preferences after a simple contructor call, as if it were in some uncompleted state. I read lots of related topics, but wasn't able to find a solution. Basically, I need to share these credentials among activities in my application
That's not how you create Activities. When you just call new Login(), it doesn't have a correct context to access the shared preferences. You should also NEVER, EVER call new on a class that extends Activity or Service. That's not how android classes work.
You'll need a way to get a reference to the Activity.
But it sounds like your design isn't correct. You shouldn't need to get at another activity's preferences. If you do, just put it in the defaultSharedPrefernces instead.