Saving structured data in android - java

Android provides some ways to save application information. http://developer.android.com/guide/topics/data/data-storage.html
Now, my issue is that I have some structured data comparable with tasks, that have categories and some other related settings. Everything is fetched from a web service and has to get saved for performance and offline use.
Which would be the best option to use on Android? I think the choice is really between SQLite Database or Internal storage. What would I expect from the performance and implementation choosing one of the options?

One really easy way to cache data is to just Serialize your objects and save them to the internal cache e.g:
// Example object which implements Serializable
Example example = new Example();
// Save an object
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(getCacheDir(),"")+"cacheFile.srl"));
out.writeObject((Example) example);
out.close();
// Load in an object
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File(new File(getCacheDir(),"")+"cacheFile.srl")));
Example example_loaded = (Example) in.readObject();
in.close();

If your web service gives you an XML or JSON, you can just save it on a file, and then read it from the file. It's like "caching" data.

Related

How to read File and convert it to Hashmap? [duplicate]

I have a data structure that I would like to be able to write to a file before closing the program, and then read from the file to re-populate the structure the next time the application starts.
My structure is HashMap<String, Object>. The Object is pretty simple; For member variables it has a String, and two small native arrays of type Boolean. This is a real simple application, and I wouldn't expect more than 10-15 <key,value> pairs at one time.
I have been experimenting (unsuccessfully) with Object input/output streams. Do I need to make the Object class Serializable?
Can you give me any suggestions on the best way to do this? I just need a push in the right direction. Thanks!
EDIT: Well I feel dumb still, I was writing from one map and reading into another map, and then comparing them to check my results. Apparently I was comparing them wrong. Sigh.
If you aren't concerned about Object particularly , you just need key value pair of String,String then I would suggest you to go for java.util.Properties. otherwise here you go
Map map = new HashMap();
map.put("1",new Integer(1));
map.put("2",new Integer(2));
map.put("3",new Integer(3));
FileOutputStream fos = new FileOutputStream("map.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(map);
oos.close();
FileInputStream fis = new FileInputStream("map.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Map anotherMap = (Map) ois.readObject();
ois.close();
System.out.println(anotherMap);
Map m = new HashMap();
// let's use untyped and autoboxing just for example
m.put("One",1);
m.put("Two",2);
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("foo.ser")
);
oos.writeObject(m);
oos.flush();
oos.close();
Yes, your objects will need to implement Serializable in order to be serialized by the default Java mechanism. HashMap and String already implement this interface and thus can be serialized successfully.
Take a look at Sun's own Serialization tutorial - it's quite short and I think should cover everything you need for your simple case. (You should just be able to serialise the Map object to the stream, and then read it back in on subsequent runs).
If you do run into problems, try serializing a simple HashMap<String, String> with some dummy values. If this succeeds, you'll know that the problem lies (somehow) with your own class' serializability; alternatively, if this doesn't work you can focus on the basic structure before throwing your own class into the mix.
Post back if you have any more specific problems that you can't figure out on your own.
Yes, if you want to write an object to the file system, that object must implement Serializeable. Here is a tutorial that should help you out.
Don't bother with making it Serializable until you understand more about what that's used for. You want to look at FileWriter and google "java file io" A good way to write this data is as CSV.
eg.
key1,key2,key3
valuea1,valuea2,valuea3
valueb1,valueb2,valueb3
Hope this helps.
SERIALIZE A HASHMAP:
This code is working fine , I have implemented and used in my app. Plz make ur functions accordingly for saving map and retrieving map.
Imp thing is, you need to make confirm that the objects you are putting as value in map must be serializable , means they should implement serailizbele interface. ex.
Map<.String,String> hashmap=new HashMap<.String,String>().. here in this line ...map and string both are implictly serializable , so we dont need to implement serializble for these explicitly but if you put your own object that must be serializable.
public static void main(String arr[])
{
Map<String,String> hashmap=new HashMap<String,String>();
hashmap.put("key1","value1");
hashmap.put("key2","value2");
hashmap.put("key3","value3");
hashmap.put("key4","value4");
FileOutputStream fos;
try {
fos = new FileOutputStream("c://list.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(hashmap);
oos.close();
FileInputStream fis = new FileInputStream("c://list.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Map<String,String> anotherList = (Map<String,String>) ois.readObject();
ois.close();
System.out.println(anotherList);
} catch (FileNotFoundException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
} catch (ClassNotFoundException e) {e.printStackTrace();
}
}
I'd advise against using Serializable; it is much harder to do properly than it first seems. It would seem that simply adding implements Serializable is all you need to do. But in fact this adds many restrictions on your code that are difficult to deal with in practical software development (rather than in school). To see just how horrible these restrictions are, see the book Effective Java (second edition) by Bloch.

NotSerializableException with java.awt.geom.Area

I'm creating a game where all locations of 'blocks' are stored in the variable block_area - an object of class Area. My game has been running correctly for a week now, and I've decided to implement a save and load feature where I save block_area to a file Drifter, with this as my code:
Area block_area; // Later initialized
void saveArea()
{
try
{
FileOutputStream fos = new FileOutputStream(savefile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(block_area);
oos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
void loadArea()
{
try
{
FileInputStream fis = new FileInputStream(savefile);
ObjectInputStream ois = new ObjectInputStream(fis);
block_area = (Area)ois.readObject();
ois.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
However, this is my very first time writing and reading an OBJECT to a file, so I don't know much about it. When I try to save the object to the file, it gives me this error:
java.io.NotSerializableException: java.awt.geom.Area
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at Drifter.saveArea(Drifter.java:58)
at Drifter.keyPressed(Drifter.java:315)
...
If anyone can tell me how I can go about writing and reading an object with a file, the help will be greatly appreciated.
TL;DR How do I write the contents of an Area object to a file and read it?
ALSO I have a few follow-up questions:
Is ObjectInputStream the best course of action here? I have seen a few answers where people recommend using XML, and JSON, but I can never find the time to learn about them, and would prefer to stick to a pure Java method (without any third party tools)
Is there any other method of saving an object's information to an external source that I can use instead of file handling?
EDIT - I should also mention that my class implements Serializable
The exception is pretty self explanatory NotSerializableException: java.awt.geom.Area . Any object that you want to serialize must implement the Serializable interface. java,awt.geom.Area does not. Any attributes of that class must also implement Serializable, be a primitive, or be defined as transient.
I'd suggest either Figuring out a way to read Area into an object that does implement Serializable. When you read it back out, you can construct a new Area object. This is probably what the JSON/XML method mentioned in the comments is doing. The added benefit of a human readable storage format is that you can edit it in a text editor. You won't be able to do that with the binary output of a serialized object`.

Add item to serialized list in a file

I have an ArrayList of a Serializable, which I can serialize then save and load it from a file. But what if I want to add an object to the arraylist, without loading the whole list, then saving the whole thing again? I don't feel like loading the whole list, then adding an object to it and then save it again, as it would impact my performance.
These are the two method I've made for saving and loading the file. The Deck class of course implements Serializable.
public static List<Deck> loadDeckDatabase() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("decks");
ObjectInputStream ois = new ObjectInputStream(fis);
List decList = (List) ois.readObject();
ois.close();
return decList;
}
public static void saveDeckDatabase(List<Deck> decks) throws IOException, ClassNotFoundException {
FileOutputStream fos = new FileOutputStream("decks");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(decks);
oos.close();
}
I hope someone can help me. Thanks!
Either:
You have to load and save, as you don't know how the Deck is serialized.
You can to write your own serialization so you actually know how to append.
See also here:
https://stackoverflow.com/a/7290812/461499
Why don't you just use SQLite database? It is light, local (stored just in file) database supported by Java. The way you are using it is same that using common database.
Look at the tutorial here: http://www.tutorialspoint.com/sqlite/sqlite_java.htm
If you don't want to use the database I see two ways to dealt with you problem:
Keep every array object in other file and keep a files counter in some place - which is not very elegant solution and I guess it will increase I/O operations count
Serialize your structure to JSON and write your own method to add element. Since JSON's structure is very simple it seems to be quite easy to just add new element with simple file and string operations

How to Serialize/Deserialize an object without implementing Serializable interface?

If a mail is send to my inbox, I recieve a message, and I'm inserting the contents into DB.
I have a org.springframework.integration.core.Message something like follows:
public void receive(Message<?> message)
{
//I am inserting message contents into DB
}
Now in the event of failure, I wanted to have fail safe recovery mechanism, what I am thinking is to serialize the Message object into a file and later deserialize and update to DB.
Question
1. In this situation how to serialize the Message object?
2. Other than serialization any other mechanism that can be used?
EDIT
I have not done Serialization before, I heard like the class should implements Serializable in order to use ObjectOutputStream, in this case I don't want to create a subclass of Message, So how to serialize Message to File?
Sure, there are many serialization mechanisms apart from the jvm one.
XML
JSON
BSON
MessagePack
protobufs
...
Some of them are text-based, some are binary. All have drawbacks and pluses. Text-based ones are human-readable, binary ones are faster and take up less space.
There are java libraries that handle all the above formats: JAXB (XML), Jackson (JSON), etc.
In this situation how to serialize the Message object? Other than serialization any other mechanism that can be used?
Extract all the data you need from the Message and save it. You can do this in any manner you choose.
You can deserialize it by populating a new Message with the data you saved.
I don't know if I probably understood it al right.. but assuming Message is not much more than lots of strings and some integers you can just use directly an ObjectOutputStream and write it to a file (binary) and then readin later. Why not?
Message e = new Message();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("whatever");
oos.writeObject(message);
// read in
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("whatever");
Message e = (Message) ois.readObject();

Java - create dynamic variable table that I can easily call back variables

I am a newbie programmer, very newbie..
I am trying to write a program to test our website and am using Java and Selenium.
The issue is I want to create a "table" or a "reference" that will allow me to store variables that can easily be called back and used in different calls.
I tried to use a HashMap but found it was no good because when I rerun my testing code there is a new hashmap each time. I want something that can store the values and remember them the next time I run the code.
I looked at creating a mysql table but I can't figure out how to recall the variables out of the table once they have been created.
I hope this makes some sense. :0) Pls check out below if an example would be more useful
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Here is an example of the hashmap that I was using:
HashMap idTable = new HashMap();
idTable.put("GroupName", new String("Group " +
Long.toHexString(Double.doubleToLongBits(Math.random()))));
element = driver.findElement(By.id("name"));
element.sendKeys((String)idTable.get("GroupName"));
FYI: The reason this doesn't work for me is that I want to be able to wrap it in an "if" statement; to tell the computer that if the variable called "GroupName" already exists then don't do it again.. however every time I run the script I make a call to the function [HashMap idTable = new HashMap();] and I don't know how to NOT make that call because the HashMap isn't saved anywhere.. it is created new each time.
Thanks,
Orli
not sure where to add this: but following the first suggestion here is what I did.
HashMap idTable;
try{
ObjectInputStream is = new ObjectInputStream(
new FileInputStream("C:\Documents and Settings\My Documents\Selenium local\hashmap.dat"));
idTable = (HashMap) is.readObject();
}
catch(Exception e){
idTable = new HashMap();
}
AND then:
try{
ObjectOutputStream os = new ObjectOutputStream (
new FileOutputStream("C:\Documents and Settings\My Documents\Selenium local\hashmap.dat"));
os.writeObject(idTable);
os.close();
}
catch (Exception e){
}
It works. :0) Thanks for the help!
Use an instance of Properties for simple string key/value pairs. It is a Map, like HashMap but has load and store methods for reading/writing its contents to a file. This should be more than adequate for simple testing usage.
It is commonly used for loading configuration files.
You must store them somewhere not in the code, as the code goes bye-bye whenever the JVM shuts down. Two good options to do this are
Using SQL database, research this more via google if you want
Via files, simply writing your HashMap database to a file at the end of your program (Do Runtime.addShutdownHook, and pass it a thread whcih stores your hashmap to the file), and have it read from the file at the begining of the code (if the file is nonexistant, make a new one, and store an empty hashmap to it)

Categories

Resources