I made an android game and I want to know how to save player data such as money, level reached, etc. I think that XML is not a really convenient way to do this. Is there any good way to do this? Does android provide some method to save the data?
A database is probably overkill for the type of data you need to track. I would suggest using Android's SharedPreferences APIs. See here for a tutorial.
Here's an official overview of Android data persistence methods including SharedPreferences and SQLite.
Check out the getStringSet API for storage of arrays/collections.
For non-existent vals for the string set:
Returns the preference values if they
exist, or defValues. Throws
ClassCastException if there is a
preference with this name that is not
a Set.
For non-existent value data such as string, bool, float etc.:
Returns the preference value if it
exists, or defValue. Throws
ClassCastException if there is a
preference with this name that is not
a String.
Use a SQlite database. ( Data storage on developers.android )
Here is a tutorial that shows the functionality:
http://p-xr.com/android-tutorial-simple-but-persistent-data-storage/
Related
If I have a class containing of integers, strings and a Date, how should I go about creating, saving and displaying a new instance of this class in my ListViews?
I've used SharedPreferences before for saving local strings but is this possible with objects as well, or should I look into SQLlite?
Edit: Also, if SQLlite is needed, a little steer in the right direction would be appreciated.
You can still use preferences to save your objects but you need to serialize them into strings. And for later use you have to deserialize them from strings into your list of objects. This can easily be done with Json.net but I would recommend to use a database like SQLite. This would make it easy if new requirements like searching or object extension comes up.
A good entry into SQLite and Xamarin can be found here or here.
I have implemented a standard LRUCache in Android that stores Objects. Each key is a unique ObjectId associated with the Object stored. My problem is that the only way to retrieve an Object from cache is by the ObjectId (no iterator). What would be the best way to implement a getAll() method?
Another option would be to store all the ObjectIds in a list somewhere, so I can iterate over the lists and get all of the Objects - but what would be the best way of holding all of the ObjectIds?
Thanks!
If you're using (or extending) the LruCache that Android provides, it has a snapshot method that returns a map of keys (your ObjectIds) and values (your Objects). You can do something like this:
Map<ObjectIds, Object> snapshot = lruCache.snapshot();
for (ObjectIds id : snapshot.keySet()) {
Object myObject = lruCache.get(id);
}
If you're not using Android's LruCache, then I imagine it would depend on your implementation. (I'd also be curious what motivated you to implement your own instead of subclassing the provided one!)
Using snapshot to get current collection at the moment
lruCache.snapshot().values()
It does not make sense to iterate over the objects in a LRU cache. You can not know which object is still in the cache and which got evicted (you actually can, but that's another story). It sound like you'd probably better off with a different data structure like a Hashmap or so. Nothing will ever get evicted from there.
A common use-case is to have a List of all possible object keys in memory. If you need one, you check if it is in the cache. If not, receive it and add it to the cache.
I am currently using SharedPreferences for both my preferences and my data. Realizing that getting all of the values for my data out via prefs.getAll() actually gets both of my SharedPreferences which is incredibly annoying.
What is the best route for my data. It is key-value with the keys being dates and the values being floats. (Actually ideally I'd have two floats for every key, but I could traverse two.)
Can I make a Hash Map in my activity and inflate/deflate as normally and send it to my fragments as I need the data?
Your question is asking a few different things, so I'll try answer them all.
For storing data that is too complex for shared preferences, you should look into using an SQLite database. There are some good libraries that make it very simple - check out ActiveAndroid or OrmLite.
If you want to stick with shared preferences, but want to solve the issue of getAll returning the preferences and the data, you can actually create 2 separate sharedpreferences. There is a method getSharedPreferences (String name, int mode) which takes a name. Use the default shared preferences for your preferences, and create a shared preference with a different name for your data.
As for sending data to your fragments, you can use a Bundle. Bundles take all sorts of data, and serializables as well, so that should be no problem. Put your data into a bundle and pass it to your fragment when its instantiated.
The ContentValues class contains a method that allows Booleans to be put into the values collection. AFAIK, SQLite does not contain a native Boolean format that Android could push the boolean values into. So, what magic does Android do behind the scenes to store these values?
Also, why is there no complimentary getBoolean method on a Cursor? To me, this appears to be a pretty awkward design oversight since there seems to be no "safe" way of retrieving a boolean value that was put into the DB via ContentValues. What am I missing?
This question may seem a bit frivolous since I suspect that the boolean's are stored as a 1 or 0 integer, but why would Android commit to developers making that assumption? Its not even documented as far as I am aware.
The ContentValues class contains a
method that allows Booleans to be put
into the values collection. AFAIK,
SQLite does not contain a native
Boolean format that Android could push
the boolean values into. So, what
magic does Android do behind the
scenes to store these values?
From reading this document, it sounds like the boolean to integer conversion is done by SQLite.
Also, why is there no complimentary
getBoolean method on a Cursor? To me,
this appears to be a pretty awful
design oversight since there seems to
be no "safe" way of retrieving a
boolean value that was put into the DB
via ContentValues. What am I missing?
If you're reading from a cursor, then you know what columns should be returned from the query, so you presumably know the data types of the columns that were requested. I agree that having a getBoolean method would be better, but it's not hard to work around.
UPDATE
Google has patched the previously mentioned bug, though it's not implemented yet at the time of this post:
https://code.google.com/p/android/issues/detail?id=232274
It's worth noting that the current API is dangerous and could break your app if anything changes under the hood.
Additionally, ContentValues.getBoolean has a major issue that if you create the ContentValues with DatabaseUtils.cursorRowToContentValues it will treat EVERY field as a string:
values.put(columns[i], cursor.getString(i));
When you then retrieve the field via ContentValues.getBoolean you will ALWAYS get false:
if (value instanceof CharSequence) {
return Boolean.valueOf(value.toString());
Since value is "0" or "1" this conversion fails:
private static boolean toBoolean(String name) {
return ((name != null) && name.equalsIgnoreCase("true"));
So I highly recommend that you create your own getter and setter so your behavior is well defined.
My app has around 25 items that users can change attributes on. They can show/hide them, set the text, change the color, etc. And they can save multiple sets of these settings.
I'm trying to come up with the best way to handle this. I could use sharedpreferences and store the value of each attribute for each of the ~25 items and prefix them with the name of the saved set of settings. Then regardless of if any changes were made, load the values for everything on start/selection of a new set and save all values on close/save of new set.
I'm not sure that's the best way though. Anyone have ideas on how to do this?
PreferenceActivity is very powerful for such cases.
You can serialize your java objects that implements Serializable interface. Then you can save this serialized string to an internal file. Afterwards you can get these objects by deserializing objects. By using this method your data will be private and nobody will see your data, this is not the case when you use sharedpreferences. This method is very flexible so that you can save all objects that implements Serializable interface. I am using this method to save my preferences.