Writing to shared preferences too slow? - android

I have created a service that writes some information about a widget once a user places it on home screen(the info is picked up from the confutation activity)..i also write down the number of widgets the user has set up.
Once the user removes the widget i delete that info in the shared preferences.
What i have experienced is that if user places for example 2 widgets, then removes one, then places one again, doing all those actions fast, the shared preferences file gets inconsistent values in it. Sometimes it works ok but most of the time i get stuck with wrong values in it.
I am using apply(), i've tried with commit but same thing happens.
The values i store in the shared preferences are crucial for the system to work, without it the widgets are useless since they are backed up by info from internet based on the user configuration which is written in preferences.
Is switching to a database solution more reliable or any other viable solution which will fix this "race condition"? (maybe forcing my own mechanism of synchronization, but as far as i've understood from docs, apply() is already synchronized, and the read/write should first go to RAM which should make it fast and i shouldnt be experiencing any problems like this since the user cant physically manage to delete a widget and place a new one faster then 2-3 seconds top!)

Try using the synchronized keyword in working with the SharedPreferences itself. For example, here is a method that could be used when setting an application String in the SharedPreferences of an Android app:
public synchronized static void setAppString(Context context, String pref,
String val) {
SharedPreferences sp = context.getSharedPreferences(
APP_PREFS_UNIQUE_ID, Context.MODE_PRIVATE);
Editor editor = sp.edit();
editor.putString(pref, val);
editor.commit();
}
For few/simple key-value pairs, you might not need the overhead of a database paradigm.

Related

How to save number of times a user has tapped on a view

I am designing a simple application that will count how many times a user has tapped on a imageView. My question is what would be the best way of saving and reading this file. Any suggestions? I am thinking something like using Parse.com's local database. I have tried it, but I could not get it working the way I wanted. I am still a beginner, so please not so fancy suggestions.
Try to save data in SharedPreference. SharedPreference works like database for application on device that will be stored until any one has unistall app from device.
To create sharedPrefernce-
SharedPreferences prefs = this.getSharedPreferences(
"com.example.app", Context.MODE_PRIVATE);
To store data -
prefs.edit().putInt("key", int_value).apply();
To retrieve data-
// use a default value
int l = prefs.getLong("key", default_value);
Simplest options is always thebest option, go with shared preferences
Here is simple tutorial from google http://developer.android.com/training/basics/data-storage/shared-preferences.html
It will store your data in application local file. Take a note of that there are different shared preferences in example getPreferences() will return file specific for activity you used this method. While getSharedPreferences() will return application global file.

When to use getSharedPreferences vs savedInstanceState?

I'm trying to figure out when to use a saved instance state versus loading information from a shared preferences file. I have two variables that I wish to save, time and score. I want to make sure that if the user returns to the game screen that their score and time is saved and restored regardless if it's from onPause state or onStop.
I have three keys:
public static final String ARG_SCORE = "score";
public static final String ARG_TIME = "time";
public static final String SHARED_PREFS = "shared_preferences";
If the game is paused and a dialog is shown, when the user returns should I do
public void onRestoreInstanceState(Bundle savedInstanceState){
int score = savedInstanceState.getInt(ARG_SCORE);
}
or should I do something like:
protected void onResume(){
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int score = sharedPref.getInt(getString(R.string.saved_high_score));
}
Overall, I need help understanding the lifecycle and when to store vital information such as time and score of the game. I simply need to avoid the user having to restart in cases they weren't able to finish the game.
Lastly, I'm assumed that the sharedPrefs saves to an xml file. Is this correct? Does anyone have a sample xml for how my sharedPrefs should appear? Do keys which are saved to bundles of savedInstanceState get stored in xml files as well? If so, any examples? If not, where is the information stored?
THANKS!
edits:
ok cool beans. Thanks! One more question, when defining a key for a key-value pair stored into sharedPreferences such as
public static final String ARG_SCORE = "score";
why is the "score" string stored? When would this ever be used? I've always placed a value into the key_value pair using something like
args.putInt(ARG_TIMER, timerINT);
and retrieved using
scoreINT=savedInstanceState.getInt(ARG_SCORE);
Why is a name needed for the key ARG_SCORE? When would I need the name? Does it have to stay type String?
use saveInstanceState when you are frequently moving back and forth between activities and use SharedPreferences when you want to keep information for long time and yes sharedpreferences stored in an xml file. you can view using DDMS in eclipse.
Remeber, in saveInstanceState, when you close app mean it get removes from memory, information will also lost. And in SharedPreferences, information will remain there if you close your app.
It will depend on how you want to manage the data. Both options (and more) are feasible:
If you want to fill once and keep the data even if the app gets
killed, use SharedPreferences.
If it's volatile data that will have to be reentered differently some
other time (i.e., days later), then use onSavedInstanceState.
If you want to keep multiple datasets on the same device, then use a
SQLiteDatabase
You usually want to use SharedPreferences when you want to persist some information between different app session. Imagine you want to store information that you want to retrieve also after the user closes the app.
SavedInstanceState is used to keep some information while user is using the app and allow you to track temporary state of your activity or fragments.
Hope it helps.
when you press home button then still your activity remains in background. since there is some memory constraints in android , there is always chance some other application can take your memory. so to resume application from same point where we have left we use saveInstanceState.
we use sharedprefrence when we have to save small info(normally primitive type) like game high score in any game.
In the Android documentation says how to relate SharedPreferences to XML but there's no need to use SharedPreferences if you don't want the data to be stored forever, you can store the game's state using the Activitys lifecycle methods with no problem, but for example, if the user turns off it's phone or presses the back button to finish your Activity, then the savedInstanceState won't work and you will lose your data.
It's your call, if you want the game to be saved even if the user turns off his phone (I think this would be kinda radical, but if it's your requirement go ahead) then use SharedPreferences or a DB if it's complex data. If you want the game to be saved only when the user navigates in and out to your app, then it's safe to use the savedInstanceState.

Android: Using self-defined metadata

I want to make an Android application which shows questions on the go on the basis of user selection. But I won't use a server, and so the questions have to be bundled with the app. But adding the whole questions would not be a great design, so either SQLite database can be used, or xml metadata can be used. But SQlite bundling I heard makes the app large in size. Is that so? And could someone explain how to refer to a xml file with self-defined metadata, to create questions on the fly. What will be the best way to do this?
the SQLite DB is on the phone already, I've used it a few times with no big jump in .apk size.
If you are looking for an easy-to-use stored hashmap, try SharedPreferences! Though I wouldn't use it for a heavy solution, the implementation guarantees ACID and is very straightforward. you can make several different hashmaps and name them different things with SharedPreferences http://developer.android.com/reference/android/content/SharedPreferences.html
I declare:
private SharedPreferences anchorHash;
in onCreate:
anchorHash = getSharedPreferences(getString(R.string.anchor_hash), MODE_PRIVATE);
inonPause:
SharedPreferences.Editor editor = anchorHash.edit();
editor.clear();
for( String s: anchors.keySet()){
//it's a another hashMap I want to write here, but you can do this however you like
editor.putString(s, anchors.get(s));
}
editor.apply();
//or commit() if you need to know about the success ( it'll happen )

Saving Shared Prefrences in Multiple instances

I would like to be able to save my users session or sharedPrefrences in a way that if the user kills the application and you start it it would look like this.
Button one = Start Activity with Blank Preferences
Button Two = List of Saved Sessions of Preferences and once clicked all put into the Starting activity.
Is this possible and if so how would I go about doing that?
Thank you!
Yes you can do that and it is good to use sharedPreferences if you just have to store some session variables. But if it is more, then go for database.
Do clear sharedPrefences in your application you need to do this:
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity);
Editor editor = settings.edit();
editor.clear();
editor.commit();
For reading the preferences, you can keep a sharedPreference with the count for the seesions. While saveing the prefences, always save with the strings session1, session2, session3 etc. So, while accessing them based on count, prepare a loop and form the string and access all the session variables and show them.
The reason why I didnt suggest you to do getAll() for sharedPreference is that, you may save few other things in sharedPreference. So by forming strings yourself, while reading you can just get the sessions and not other data saved in sharedPreference.
I hope you understand what I meant
Is this possible
I would say yes, depending on exactly what you mean.
if so how would I go about doing that?
SharedPreferences has a couple different functions to do something like this, depending on exactly what you want. You can get a Map of all preferences that are stored after clicking Button2 with getAll() or a set of preferences with a certain String such as "userName" or something similar with getStringSet(). Play around with the functions it offers and see if it gives you what you are looking for.
Also take not of the warnings of these functions
Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.

How to attach a Preference to a particular SharedPreferences?

I am working on implementing the preferences for our application. I know how to display preferences UI and how to read/write values using SharedPreferences. In our app, I need to handle two sets of preferences and I would like to ask about this issue, one comment in the Android documents in particular.
The documentation for Preference.getSharedPreferences() has the following comment under the Return values section:
Returns The SharedPreferences where this Preference reads its value(s), or null if it isn't attached to a Preference hierarchy.
I would like to ask how it is possible to attach a SharedPreferences to a particular Preference, be it EditTextPreference or others. In other words, how does the persistence code in a Preference know that it should store the user input in one particular SharedPreferences object and not the other?
To explain my question further with an example, suppose I have the following:
SharedPreferences prefs1 = getSharedPreferences(file1, mode);
SharedPreferences prefs2 = getSharedPreferences(file2, mode);
My question is what API I should use so that prefs1 is used by the Preference objects' persistence code and not prefs2.
The target is Nexus One, running 2.3.4.
Maybe the answer is obvious but I could not find it after reading the documentation and searching the web. Thank you in advance for your help.
In other words, how does the persistence code in a Preference know that it should store the user input in one particular SharedPreferences object and not the other?
Preference uses PreferenceManager's getSharedPreferences(), which eventually routes to getDefaultSharedPreferences().
You are welcome to create your own Preference subclasses that change this behavior, but since the preference screen system may not be designed to handle multiple SharedPreference objects, there's a chance that your preference changes might not get persisted.
IOW, I encourage you to reconsider:
In our app, I need to handle two sets of preferences

Categories

Resources