I've been making an app on my free time for Android. I was looking your advice on to how store some data objects I have.
Today the objects are stored in the shared preferences, but as more and more objects are added with more properties I would hate to keep filling my shared preferences.
In short, today I want shared preferences but later I might choose to store in the SQLite database.
I've looked around for ORM based projects for Android and found a few. However, most of them are tied with a database and not the shared preferences. I am not even sure if some are customizable enough to add my own persister.
I could go on my own and perhaps write my own persister scheme. In fact, that's what I've done so far but it seems to basic and not so powerful.
Any ideas on what would you do?
First and foremost, if you are going to use a database (SQLite) then you should consider using the DB controller API Android already provides. http://developer.android.com/guide/topics/data/data-storage.html#db now you don't have to use that and can tie into the DB yourself. This is not recommended due to what you are experiencing right now... how to evolve and grow.
The controller doesn't care where you get the data from, it might be a DB or a web service etc.., so you can change the where you get the data from without changing how the data is passed about and handled.
Sorry for the breavity, I am not at my desktop currently. Bottom line is, SharedPreferences are powerful for sure but they are just a tool and should be used as intended... used for storing simple key/value data.
Related
I want to write an android calculator app like the one on my android phone. It saves history for operations and by clicking a button it shows last operations. Now my question is what is the best way to save operations? Is it reasonable to save them to a file in internal storage or what?
There's some options..
1) Include a SQLite Database, as others mentioned. This makes storing lots of information really easy. You can find tutorials on how to include one properly in your project, and don't hvae to care for much more. You can then work with content providers to read and store data.
http://developer.android.com/guide/topics/providers/content-providers.html
2) SharedPreferences. If you just intend to store like the last, or the last 3 Operations, you can just use shared Preferences. This is way less overhead than adding a Database, if it is a small project, albeit you will have to keep your data structured yourself.
http://developer.android.com/reference/android/content/SharedPreferences.html
3) If you just want to store the users current session you can just Keep a Stack of the used operations. On undo, or however you call it, you would just pop the stack.
By implementing onSaveInstanceState and Parcelable you can make sure that no data is lost on rotation / low memory and such.
I personally would advise you without knowing more about your project to use plain java objects and storing the state. A calculater would in most cases not need persistent storage. If you really want to know what the user did 2 weeks ago, you should use a Database.
I would recommend you to use database(SQLite) for storing the data.
If you don't know more about SQLite in android have a look at these
tutorials.
I think database should be handy for history if more than one operations has to be stored else for one operation you can use shared preference.
In my android application I have to store some application settings and some user information within the phone.
I can go for the shared preference option explained in this DOCUMENTATION.
But wondering if I can store data as objects wise within the phone. I found this Stackoverflow Question regarding saving serialized objects in files and bit not sure of any issues if I go with this way to store persistent data.
Also would like to know what the best way to deal with insert/delete/update and read with XML files in android. Would appreciate any guidance. Thanks in advance...!!!
If it is only a small amount of data you need to store, then go with the built-in shared preferences, that is what the functionality is there for. SQLite and OrmLite are a bit heavyweight in this situation IMO. Even if you want to handle the data as Objects; in which case I would serialise to / deserialise from JSON or XML stored in text files and handle the insert/update/delete on the deserialised objects in your model.
If you want to persist some objects I think you should use SQLiteDatabase, it would be a more cleaner solution than using serialization in files. You will indeed need to write some extra code for your Database but you will end up with a cleaner implementation in my opinion. You could also be using OrmLite for Android which is pretty robust and easy to use if you have some basic orm knowledge.
I can't choose between SQLite and SharedPreferences.
I can use
JSON.parse(SharedPreferences.getString("data","qweqwe");
and
s.putString(key,JSON.stringify(JSONObject));
Or create a new, big class to store my (text) data in SQLite. (PS: JSON.* is my own class)
What will be faster, better?
I know that SharedPreferences is for "key-value" data, SQLite - for big amount of structured data. But in my case storing JSON-formatted data in SP and accessing by key would be easier. Main question - will it be slower or faster? Pros and cons?
On the one hand this is a slightly subjective question (and not the best fit for stackoverflow). On the other hand, taking your question title literally, the objective answer is "No, it's not bad".
The reasoning is, however, slightly subjective as it 'depends' on the situation.
The SharedPreferences class is effectively a wrapper / helper for a file stored in an app's private (internal) storage - as I understand it, it's an XML file. Based on that fact, ask yourself again..."Is it bad to save a JSON-formatted string in an XML file"?
As you mention in the commen on your question, using a SQLite database will mean writing extra code whereas the advantage of SharedPreferences is that a given preference file is accesible by name by any Android class which extends Context including Application, Activity and Service.
I thought about this and had some practice.
So, using SQLite (in my case) is better that using JSON-formatted string in SharedPreferences, because I can just update only one-two rows from a table. With SharedPreferences I have to:
use new JSONObject(sharedPreferences.getString("json_string","qweqwe");
some manipulations with object
edit my SharedPreferences.
seasoning to your taste
Put my JSONObject().toString() back into SharedPreferences. It's all.
IMHO, it's more complicated for the device. Because it cannot be seasoned
If I wouldn't need to update an individual parts of data, I'd rather to use SharedPreferences, because for static data, which I don't need to update, is faster.
I have used this approach in several projects without any issues so far. But there are certainly several advantages to using an SQLite database; particularly, the versioning/upgrade features of SQLite, and the powerful SQL querying language. If you ever need to migrate data to a new structure of storage, the upgrade and onUpgrade callbacks in the SQLite framework can be immensely helpful.
If you are keeping it simple, JSON in preferences can be very quick and extremely easy to implement. In terms of security, preferences are slightly more "exposed" than a database in that they are simply stored in xml, but ultimately the database file for an SQLite database is stored the same way and can be read during an intrusion as well.
I haven't had any performance issues using JSON/SharedPreferences yet, but I also haven't done any profiling to test this. My mindset has been to keep the code simple and not optimize prematurely - if performance issues arise, do the work of profiling it at that point.
Ultimately, I'd say that there is nothing inherently wrong with using SharedPreferences in this manner.
My app needs to store data on the phone, but I'm not sure what's the more efficient method. I don't need to search through the data or anything like that. I just need to be able to save the app's current state when it closes and restore when it's back up. There is between 1mb and 10mb worth of data that will need saving.
There are basically a bunch of custom classes with data in them, and right now I have them as Serializable, and just save each class to a file. Is there any reason for me to change that to store it in SQLite?
If you where to use sqlite you could save as you go, and know that whats in the DB is pretty much uptodate if the app/activity holding the data is suddenly killed by the os. Other that that I cant see and obvious reason to use sqlite for your use-case.
Also for the sql approach you have a clear cut way to change the structure of your domain objects at a later time and to migrate the data from a old to a new version of your database. This can be done using serialized objects as-well, but then the objects needs to be duplicated, both new and old at the same time. And that to me sounds very very scary and messy, especially considering that you might need to go from version x to y, so you might end up with some pretty tricky problems if you ever need to update the domain objects.
And I can honestly not see any benefits of using the flat-file/serialized approach.
You mention in your question that the data is only meant to save the state of the app, therefore my initial response would be to keep it on the devices especially since you mention that the file size would not be much more than 10MB, which is quite reasonable.
So my answer to you would be to keep it as is on the device. If your usage of the information changes in the future, you should then reconsider this approach, but for now it's totally logical.
If you're only saving serialized classes, you could use an ORM mapper as discussed in this thread . This saves you the inconvenience of writing your own mapper and is easily extendable to new classes. Also, if your requirements change, you COULD lookup data.
The only reasons for changing your system to SQLite would be more comfort and maybe a more foolproof system. E.g. now you have to check if the file exists, parse the contents etc. and if you'd use SQLite, you don't have to verify the integrity of the data and Android also helps you a little. And you could use the data for other causes, like displaying them in a ListView.
So I inherited this Android project from someone else. The code currently seems to be storing huge amounts of data (that should really belong to an SQLite database) into the shared preferences. I'm very uncomfortable with that part of the code and want to start using the sqlite database. But I am still unable to justify to myself the time it would take especially if it comes with no immediate benefits.
Of course I'm eventually going to move it to sqlite but since I'm kinda on a tight deadline I was wondering if this is worth something doing now or later.
Any thoughts and comments on storing large amounts of data in shared preferences would be very much appreciated.
Thanks
If it works now then you can definitely leave it. You are correct that the large amounts of data should go into the database. If nothing else, you'll have an easier time of querying for data.
Further research has found this post suggesting that you won't have any major problems with a large amount of data in your Shared Prefs. You could, however, have performance issues since the single Shared Pref XML file will have to be read to get any pref while with a database you only have to grab what you need as you need it.
TL;DR; Don't use shared prefs for large storage, use a DB instead (but if it works for now and you're in a rush do it later)
I wouldn't personally recommend it since the system will keep an in-memory copy of all shared prefs for your app. So if you throw a lot of data in there your memory usage will be affected. That said, and depending on the data format (whether you can use it as is and use the key to find it directly - if you just store a huge JSON object that you then have to parse or if you have to get all shared prefs to then do a linear search for the one you really need, there's little benefit in either case) and how often you have to access it, it might be faster to lookup than a file or a database since it's already in memory. It also provides the benefit of being threadsafe (a SQL DB would be as well since DBs get locked when accessed) as opposed to a file where you would have to deal with that on your own.
Hope this helps.