I have a little doubt about the SharedPreferences in Android.
To delete a preference, we mainly have two options:
First:
SharedPreferences.Editor edit = (Editor) getSharedPreferences(Constants.APP_DEFAULT_PREF, MODE_PRIVATE).edit();
edit.putString(Constants.PREF_ACC, null);
edit.commit();
Second:
SharedPreferences.Editor edit = (Editor) getSharedPreferences(Constants.APP_DEFAULT_PREF, MODE_PRIVATE).edit();
edit.remove(Constants.PREF_ACC);
edit.commit();
In either case, fetching Constants.PREF_ACC value from SharedPreferences will return null.
I was wondering which one should I prefer. Is there any memory related issues in either of them? What will the System.gc behavior be with them?
Theoretically remove is better than put(null), because it removes both the key and value (once committed) instead of mapping (and keeping) the key to a null value.
But judging by the Android 5.1.1 implementation, they are equivalent :
...
String k = e.getKey();
Object v = e.getValue();
// "this" is the magic value for a removal mutation. In addition,
// setting a value to "null" for a given key is specified to be
// equivalent to calling remove on that key.
if (v == this || v == null) {
if (!mMap.containsKey(k)) {
continue;
}
mMap.remove(k);
} else {
...
That is also what one of the putXXX methods (putStringSet) documentation says :
Passing null for this argument is equivalent to calling remove(String)
with this key.
I would recommend using remove.
When we putString or remove nothing is done, it is just marked in the Editor as TO BE DONE and gets done only when commit is called
And when the commit is called all the remove calls are executed before the put calls. So it is better to use the remove calls to remove something from the Editor.
Judging by the docs of the interface SharedPreferences.Editor for remove(String) :
Mark in the editor that a preference value should be removed, which
will be done in the actual preferences once commit() is called.
Note that when committing back to the preferences, all removals are
done first, regardless of whether you called remove before or after
put methods on this editor.
… and for putInt(int) :
Set an int value in the preferences editor, to be written back once
commit() or apply() are called.
… there seem to be only one striking difference: remove(String) calls will be "done first, regardless of whether you called remove before or after put methods".
That said, I really doubt the actual order of execution won't matter much to average use-cases, so you could just choose either one of those methods and be completely fine.
p.s., I'm still looking for the concrete class of SharedPreferences.Editor which might provide more clues about this. Will update as soon as I found one.
Related
I am attempting to do something I'm unsure of, and need someone to provide feedback.
I have 2 preferences. One of them, I want dependent on the other one's value.
Example: My "Notification Mode" Preference has 2 options: "Timer", and "Reminder"
If the User chooses the "Timer" option, I want my other Preference available to set time.
Otherwise, I want the Preference for setting the Timer to be disabled.
Here's what I've come up with inside my pref changed listener:
if (key.equals(PREF_NOTIFICATION_MODE)) {
Preference notifModePref = findPreference(key);
notifModePref.setSummary(sharedPreferences.getString(key, ""));
if(!notifModePref.equals("Timer Mode")) {
Preference timerDurationPref = findPreference(PREF_TIMER_DURATION);
timerDurationPref.onDependencyChanged(notifModePref, true);
} else if(notifModePref.equals("Timer Mode")) {
Preference timerDurationPref = findPreference(PREF_TIMER_DURATION);
timerDurationPref.onDependencyChanged(notifModePref, false);
}
}
I'm not sure if I'm doing this correctly, or if onDependencyChanged is proper.
I accomplished the Goal inside of if(key.equals) by referencing the Preference in question and using if statements and a combination of using onDependencyChanged(), and setting .isEnabled(boolean) as required.
Am using SharedPreferences to store list of values. What I need is to remove specific value from SharedPreferences.Below is my code am using to remove. But its not working.
prefs= DetailActivity.this.getSharedPreferences("itemFKID",Context.MODE_PRIVATE);
edit=prefs.edit();
//edit.clear();
edit.remove(itemFkId);
edit.commit();
Below is Screenshot that contains values even after edit.remove() compiles.
Here am inserting values into SharedPreferences
prefs= DetailActivity.this.getSharedPreferences("itemFKID",Context.MODE_PRIVATE);
edit=prefs.edit();
for (int i = 0; i < Config.favouritesList.size(); i++) {
edit.putString("itemFKIDValue" +i, Config.favouritesList.get(i));
}
edit.putInt("itemFKIDLength", Config.favouritesList.size());
edit.commit();
The documentation for SharedPreferences.Editor has two bits that are relevant to your question:
All changes you make in an editor are batched, and not copied back to the original SharedPreferences until you call commit() or apply()
And
when committing back to the preferences, all removals are done first, regardless of whether you called remove before or after put methods on this editor
So you'll have to step over the commit() call before you see the value removed.
Finally found the mistake. Key passed in remove() is wrong. Instead of edit.remove(itemFKIDValue) I have used edit.remove(itemFkID). Thanks for the time guys.
I have 2 fragments.
Fragment 1
Loads sharedpreference to display string
Fragment 2
Saves sharedprefence for string
Is it possible to retrieve that string in my first Fragment without running the second Fragment?
Yes, this is possible. You just need to make sure you are reading with the same key you used to write with:
SharedPreferences prefs = getSharedPreferences("MyPrefs", MODE_PRIVATE);
// Reading from SharedPreferences
String value = prefs.getString("myKey", "defaultValue");
Log.d(LOG_TAG, value);
Note that we've assigned a defaultValue as the return value here. If there is no value with the key "myKey" in your shared prefs, it will instead return "defaultValue". This is a nice safeguard, think of it like a null pointer check - you will always get a value from getString(), even if it's just the default.
You don't need to be in the same activity for this to work, you just need to make sure that 1) your preferences name is the same and 2) the key used to store the value is the same in both spots.
First, don't get confuse between Activity and Fragment.
And yes, you can.
On the picture you can see that the boolean variable took the default value, even though there was a key-value pair in the SharedPreferences with the right key. What can cause this? In the code this is at the end of an onCreate method. After this the onMapReady method gets called (from com.google.android.gms.maps.OnMapReadyCallback), where I check the SAME boolean value, to see If i have to place some markers on the map or not. In that method the getBoolean() behaviour is correct, the default value is ignored. This doesn't make any sense to me, anyone can help me out?
1) Did you intend the space in the key "isThereReservation " ? In your debug code, the variable doesn't have a space. Make sure you use the right key else you'll get the default value!
2) How are you saving the sharedPref? your code should be:
myPrefs = myContext.getSharedPreferences("MY_PREFERENCE_NAME", MODE_PRIVATE);
myPrefEditor = myPrefs.edit();
myPrefsEditor.clear();
myPrefsEditor.putBoolean("MY_KEY",myBool);
and then you can access by using:
myPrefs = myContext.getSharedPreferences("MY_PREFERENCE_NAME", MODE_PRIVATE);
myPrefs.getBoolean("MY_KEY",MY_DEFAULT_VALUE);
The method getBoolean return default value if the key doesn't exist. In your case, the default value is false and if the key of the SharedPreference doesn't exist is false in your case.
You are showing in debug the value of the HashMap mMap but what is the content of the eu.arrowhed.arrowheaddemo for the same key?
I am trying to develop an app that requires certain values to be set by the users at the app's first startup only, because i don't wanna bother them frequently inputting the values everytime they launch the app. My app has a single activity main and uses certain values that are inputted by the users at first startup. How can I make this possible.
Please explain me elaborately . :-)
You should use SharedPreferences to keep a track of the first use.
In the onCreate Method of your Activity (Startup activity), you could do something like this,
SharedPreferences userPrefs = getSharedPreferences("UserPrefs", 0);
Boolean firstUse = userPrefs.getBoolean("firstUse", true);
if(firstUse){
//this implies it is the first use of the app
//also once you are done implementing the logic for first use you need to put firstUse as true
SharedPreferences.Editor editor = userPrefs.edit();
editor.putBoolean("firstUse", false);
editor.commit();
}
else{
//take the user directly inside the app
}
Also, if you plan to save user information in the first use, look at different ways of storing data here.
show the alert initially and after getting the input values keep it in preference and next time check whether the required values existing or not. If it is already there avoid popup
For getting more information about shared preference check this link http://www.vogella.com/tutorials/AndroidFileBasedPersistence/article.html
preferences_statusFirst.getString("boot", "");
if (status.length() <= 0)
{
showDialog(DIALOG_birth);
editor_boot.putString("boot", "1");
editor_boot.commit();
}
else
{
}
}