Offline database in Android - java

There must be a better way to manage string values than to have a bunch of strings in strings.xml file.
I am looking for database like solution, however I don`t want it to connect to a database on the internet. It is just that I need some advanced sorting and categorising to be done that is all.
I am not very experienced with JAVA so pardon me if I just lack the knowledge.
EDIT: It would be nice that I could synchronize both database on the internet and on user`s smartphone.
Maybe effect of synchronization can be achieved by adding additional databases and sending out already modified data.

You can use a SQLite database for your app. See http://developer.android.com/guide/topics/data/data-storage.html#db

If you don't need to save them you could just use an array of strings or an array list if you have the user entering a bunch of strings or need dynamic sizing

Well, there are simpler alternatives to SQLite - you should at least consider some kind of ORM for Android.
It'll let you to persist Java objects in a few lines of code instead of using SELECT, UPDATE, and marshalling data.
Consider db4o or something like that - it's rather large (~1M), though.

Why would you want to use SQLite for this? Remember that using a database connection for this (and only this) takes up resources that could be used elsewhere. If its strings that are only used as text (which never changes) in your program you are better of using the strings.xml. Not only is it faster, but it is also a Android Standard. Besides, if you decide one day into the future to translate your application to a different language I would guess it is much easier using the strings.xml file.

Related

How to expand code/description to a complex object?

I want to present a list of the names/basic attributes of some complex objects (i.e. they are comprised of multiple collections of other objects) in a recycler view, then get the full object on user selection. For example, the top level objects are "Play Scripts", and each contains a number of "Spoken Lines" spoken by one of the "Actors" associated with the Play Script.
I'm trying to use the Android Architecture components to do this and have (using Florian # codinginflow.com 's tutorials) successfully used Room to create a simplified Play_Script class, DAO and Repository. I've also created some basic REST web services in ASP.Net which can serve up data from a MySQL db.
It strikes me that the path that I am going down will perform poorly and use excessive network bandwidth getting lots of data that I won't use. I'm getting every Play Script (including its Spoken Lines etc) just so that I have the Play Script "Name" and "Description" attributes to populate the Recycler.
In the olden days, I'd just "SELECT ID, Name, Description FROM Play_Script" and once the user had made their choice, I'd use the ID as the key to get everything else that I needed. I suspect that I'm missing something fundamental in the design of my data entities but can't come up with any keywords that would let me search for examples of this common sort of task being done well (/at all).
Please can you help this SO noob with his 1st question?
Cheers,
Z
Update 15 May:
Though I haven't had a response, from what I've been reading in recent weeks (e.g. re Dependency Injection) I suspect that there is no blanket approach for this sort of thing in Android development. It appears that people generally either retrieve extensive data and then use what they require or else build multiple Web Service APIs to return sparse data that includes keys that the client can use to expand when required. So, for example you might make both a "plays_light" and a "plays_detail" Get API.
My solution has been exactly as my May update - i.e. to extend the web API and offer a number of similar calls that return varying granularities of information. It's not particularly elegant and I suspect there may be better ways but it works. In general, I'm finding that the user tends to need less detail in the parent entities and more as we get to individual children/grandchildren.
I do now realise why some apps are so slow though: It's easy to be lazy in the web service design and just return loads of data - only a fragment of which will be used by the client - and justify this by convincing yourself that single API will be universally applicable and thus easier for whoever picks up my code down the line to understand.
Again, it could be my inexperience but I find the local caching of relational data on the Android side retrieved through the API calls quite clunky - lots of storing foreign keys and then re-parsing json to get data into the SQLite tables. I'd hoped Dagger would have been more useful in simplifying this than it has turned out to be so far. I actually unravelled a whole load of Dagger-related code just to preserve my sanity. Not sure I was entirely successful!
Better answers are still very much welcome.
Z

Accumulo, modifying previous keys using the TransformingIterator

I am currently just started writing my very own java client for accumulo.
I am able to write and read records, I now want to modify some existing keys using the TransformingIterator class (https://accumulo.apache.org/1.6/apidocs/org/apache/accumulo/core/iterators/user/TransformingIterator.html#TransformingIterator())
Since it was a while since I coded in java last time, I don't really understand how to use this class and I'm not able to find any good examples or explanations on this.
Does someone know how to use it?
Thanks.
I'd caution you against trying to use this class on your own. It has a lot of caveats that make it tricky to get correct (not to mention Iterators being tricky already on their own).
Unless you have a very large amount of data (terabytes), it is likely going to be easier to transform your data using some batch-processing tool (e.g. MapReduce) instead of trying to use the TransformingIterator.

When do I need to use in-memory datastructures instead of an SQL query?

What I aim to do as an end result is for the user to be able type into something like a textbox and a variety of options to appear as the user types letters.
As an example the user could start typing a name e.g. Jam and underneath nearest suggestions e.g. James, Jameson, Jamie etc would appear.
I know that if I use SQL's SELECT LIKE %Jam% could do the job (although I guess the user would have to stop writing to be able to execute the query; so the user can not actually see suggestions as he types.Right?).
But for my scope I would not need to use an RDBMS since the data are small and don't have real relationships between them.
I thought of using some NoSQL solution so that I look into this technology (never used it before), but in this case I am not sure on how to approach a design such as this.
Should I build a tree pre-loading all the data in the storage? So I have the data both in-memory and in-storage? But if I use a NoSQL solution isn't that usually in-memory? So I have the same data in-memory twice?
Any help on how could I approach a problem like this?
Guessing you need some Asynchronous Ajax or JQuery Autocomplete command to fetch the like items from your DB.
If its Java Swing have a look at this.
Based on your comments to your original question, I think your goals are in conflict.
If you want to learn by doing, you risk reinventing the wheel. You also risk trying to reinvent the wheel, but ending up instead with a square wheel that won't roll.
This isn't necessarily a bad thing. You can learn a lot this way, but this kind of learning conflicts with your following statement.
...I still am not sure how should I not re-implement things and follow
a standard approach.E.g. is a NoSQL a good approach for this?
The only thing that comes close to a standard approach here is to store the data on a server, not on the client. There are a lot of ways to do that, and if you object to picking "a random library that seems to do the trick", you ought also to object to picking "a random database technology that seems to do the trick".
I think the best way to learn in this case is to build your software in such a way that it knows nothing about how the data is stored on the back end. That way, you can swap out text files, a SQL dbms, a NoSQL dbms, and anything else you can dream up without affecting the front end code at all.
That's good software design--loose coupling between front end and back end.

Java DB choose for better perfomance

I have java application that process such kind of data:
class MyData
{
Date date;
double one;
double two;
String comment;
}
All data are stored in csv format on hard disk, maximum size of such data sequence is ~ 150 mb, and for this moment I just load it fully to memory and work with it.
Now I have the task to increase maximum data sequence for hundreds of gigabyte. guess I need to use DB, but I did not work with them before.
My questions:
Which DB better to choose for my
reasons(there will be only 1 table
with data as abowe) ?
Which library
better to use to connect Java <-> DB
I guess there will be used something
like cursor?!? if so, is there any
cursor realization with good record
caching for fast access?
Any other tips&tricks about java <-> DB are welcome!
Your question is pretty unspecific. There isn't a best of breed - it depends on how much money you have and what kind of hardware.
Since your mapping between Java and the DB is pretty simple, JDBC should be enough. JDBC will create a cursor for you as necessary; lost loop over the rows in the ResultSet. Depending on the database, you may need to configure it to use cursors, though.
Since you mention "hundreds of gigabytes", that rules out most of the "simple" databases. If you have money, try Oracle. If you don't have money, try MySQL or Postgres.
You can also try JavaDB (also known as Derby). But I'm not sure the performance will be what you need.
Note that they all have their quirks and "features", so expect to spend a couple of weeks to find your way with them.
Depends entirely on what you will be doing with the data. Do you need to index it to retrieve specific records, or are you stream processing the entire data set to generate some statistics (for example)? Does the database need to be accessed concurrently by multiple clients/processes?
Don't rush immediately towards SQL/JDBC, relational databases are powerful, but they add a lot of complexity and are often entirely unnecessary for the task at hand.
Again, depending on what you actually need to do, something like BerkeleyDB may fit the bill, or you may just need a more compact binary message format: check out Protocol Buffers and Kryo.
If you really need to scale things up, look at Hadoop/HDFS for distributed processing (but that's getting rather complicated).
Oh, and generally speaking, JavaDB/Derby tends to suck somewhat.
I would recommend JavaDB. I have used it in a Point of Sale system and it works very good. It is very easy to integrate into your Java Application, and you can integrate it to the same .jar file if you want.
Using Java DB in Desktop Applications may be a useful article. You will use JDBC for interfacing the database from Java, this makes it easy to switch to another database if you don't want to use JavaDB.
You'll want to evaluate several databases (you can get trials of just about any of them if they're not open source/free already). I'd recommend trying Oracle, Mysql/Postgres and with the size of your data (and its lack of apparent complexity) you might want to consider a datagrid as well (gridgain or similar).
Definitely prototype though.
I'd just like to add that the "fastest" database is not necessarily the best.
You also need to take into account:
reliability,
software license cost,
ease of use,
ease of administration,
availability of support,
and so on.

Best way to store application data when data stored and data format could change in future versions?

I'm making an Android Java app game (although this question applies to all languages really) and hope to release the first version soon. I'm nervous about how I save data in my game. My problem is that, if in a later update, I decide to store more data or store the same data in a different way, I need to be careful I don't lose or corrupt data for users that upgrade (i.e. I want users to be able to use data created by an old version in the new version, like their high scores from before).
For example, say I want to save high scores in version 1 and I use a class like:
class Score { String name; int score; }
I then store the scores in an ArrayList and then, to save/load the scores, I serialize the ArrayList object.
In version 1.1, maybe I decide I want to store the date with each score. I could then update the Score object to include a date field and use default values for date if an old object does not include a date.
In version 1.2, maybe I decide that I want to store scores in an TreeSet instead and in version 1.3 perhaps I want to load/store scores online as well.
Anyway, my point is, are there any general tips for making my life easy here? I'm particularly concerned about situations from the above, where one person upgrades from version 1.1 to 1.2 and one person upgrades from 1.0 to 1.2. Testing all scenarios for data corruption sounds like a headache.
Is it really just a case of thinking really hard to pick something sensible and scalable to start with?
I'm thinking it might be easy to use a HashMap from String->Object as a general purpose storage object e.g. storage.put("HighScoreName1", "Bob"); storage.put("HighScorePoints1", 15);. Getting the information out is a little messier than if I'd have used a custom class, but it seems easy to add extra fields and so on without much work. Iterating over lists stored in this way isn't great though.
If you are using SQLiteOpenHelper, have a look at the onUpgrade method.
Called when the database needs to be
upgraded. The implementation should
use this method to drop tables, add
tables, or do anything else it needs
to upgrade to the new schema version.
Write a version number to your output stream before you write the serialized content. I also suggest writing a magic string sequence to the front of the stream (just something that you can say is yours - maybe 5 or 6 characters). So you'll write MAGIC, then you'll write your version number. Then you'll write your serialized content.
Reading from disk is fairly straightforward - read and confirm magic. Read version. Deserialize, then pass the deserialized content on to a handler based on magic.
A couple of words of caution here, though: If possible, keep the classes you use in the serialized stream simple (String, Integer, etc...). If you use your own classes, you must be insanely careful that you never have to refactor in a way that would change the package or classname.
As tempting as it may be to just write your business objects to storage using serialization, over the long run, this is almost always a mistake. Instead, I strongly recommend developing a Configuration object. Your app initializes itself form the Configuration object. When it's time to save, the app constructs a Configuration object. Then you never, ever, ever change a Configuration class once it ships. Just create a new one (sub-classing is fine).
By separating the reading and writing of configuration objects, you can do the following pretty easily:
Read old configuration
Initialize app with old config
Later...
App creates new configuration
Write new config to file
presto - instant file format update.
Obviously, this sort of thing is tough (a lot of work, anyway) to do with big, complex data graphs - but this is Android you are talking about, so your persistent state is probably not that complex.
Note that saving as XML, or even to a SQL database is just a different form of the above strategy.
There is no definite answer, but the term you are looking for is versioning. Best serialization implementations (and file formats) can have that working both ways (old versions of the application can read files of new versions, and vice-versa).

Categories

Resources