I'm trying to write an Android game and I would like to be able to pause the game even if the user wants to return to the main menu or the activity gets killed off by the system. onSaveInstanceState doesn't seem to give me a whole lot of control as to when I can read the bundle back, plus from what I can tell, the bundle is only good for short periods of time. So I want to serialize a few ArrayLists that I have, then read them back. I don't get any compile errors nor does the program crash. But, the data either never gets written or never gets read. I'm not sure which one. My serializeData method is called in onDestroy and the deserializeData is called from onCreate. Here's my code for writing and reading the data:
public void serializeData(String filename, ArrayList<String>arrayList) {
FileOutputStream fos;
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(arrayList);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
#SuppressWarnings("unchecked")
private void deserializeData(String filename, ArrayList<String>arrayList){
try{
FileInputStream fis = openFileInput(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
arrayList = (ArrayList<String>)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
Any help would be greatly appreciated! Thanks in advance!
Let me tell you one thing: never use the onDestroy() method to save your data. Use onPause() or onStop() instead. You should never count on the onDestroy() method to save data or call some functions.
Use onDestroy to close connections and finish using resources and the like. If you want to read more about this you should take a look here.
Other than that your code seems fine. Just add one more thing: put a oos.flush() just above oos.close().
And don't forget to close the objectInputStream object.
I cannot see an obvious problem with that code.
I'd try adding some code after closing the ObjectOutputStream and before opening the ObjectInputStream to print out the absolute name and size of the file.
While serializing you can write to ByteArrayOutputStream and then decode the bytes into string using platform's default character set. Store this string into SharedPreferences. While deserializing, just get the bytes from string and create a ByteArrayInputStream using this and feed it to ObjectInputStream.Are you sure your activity is being killed? It might be the case that your activity is oscillating between onPasue/onResume.
Related
I'm trying to save a random hello world file onto the internal storage of my android. When I run my app, it simply stops.
Code:
public void saveDataOnDevice(String toWrite, String filename) {
Context ctx = null;
try {
FileOutputStream fos = ctx.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(toWrite.getBytes());
fos.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
Another question is, what Context means. I read a lot about this here, but I still don't get it.
First of all... your context is null always: Context ctx = null;, so you wont be able to make it work in any way.
To simplify: Context, in a simple app, will be your MainActivity. In a bigger app, you can have several contexts and answer will be more complex.
Back to your code, if it is placed inside your MainActivity context will be this:
public void saveDataOnDevice(String toWrite, String filename) {
try {
FileOutputStream fos = this.openFileOutput(filename, Context.MODE_PRIVATE);
// ^ --> refers to main class, in this case your MainActivity
fos.write(toWrite.getBytes());
fos.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
NOTE: if you don't have this method inside the MainActivity, you must pass a reference of your Activity to the method or the class somehow (attribute, method param, etc..etc...).
Check Android Developers::saving files for further info.
I have a a problem I have been dealing with for quite some time now. When attempting to de-serialize my custom "Sound" objects in a folder I continue to get 3 exceptions. IOException, NullPointerException, and StreamCorruptedException. Please take a look:
Method for reading sounds:
public static Sound readSound(String loc){
try{
FileInputStream fis = new FileInputStream(loc);
ObjectInputStream ois = new ObjectInputStream(fis);
fis.close();
ois.close();
return (Sound)ois.readObject();
}catch(Exception e){
System.out.println("Failed to read a serialized object.");
e.printStackTrace();
return null;
}
}
Exceptions/Errors Received: http://gyazo.com/b53faa9590adf6448bf14db11f275325
(Too much to paste here and it pastes incorrectly)
Loading the sounds:
(add sound just adds the sound to an ArrayList as well as a JComboBox)
private static File saveDirFile = new File("/Users/francisj12/Desktop/ACData/");
private static File saveDirFileSounds = new File(saveDirFile.getPath()+"/sounds/");
public static void loadAllSounds(){
if(!saveDirFile.exists()){
saveDirFile.mkdir();
}
if(!saveDirFileSounds.exists()){
saveDirFileSounds.mkdir();
}
for(int x=0; x<saveDirFileSounds.list().length; x++){
try{
File sndFl = new File(saveDirFileSounds.listFiles()[x].getPath());
Sound newSound = Serialize.readSound(sndFl.getPath());
addSound(newSound);
}catch(Exception e){
e.printStackTrace();
continue;
}
}
}
Here it what the .ser files look like: (Once I started using transient on variables so I could serialize my custom Sound object which I dont understand transient yet, it started making the .ser look as follows instead of a ton of weird characters its just one line of weird characters now)
¨ÌsrAlarms.SoundË.®ŸÓÓxp
Hope this is all the information you guys will need thanks so much for your help!
I have data coming from a bluetooth device, the data is being stored in an inputstream. I am taking the data from the inputstream and generating a graphic with Jfreechart. Whenever I turn off the bluetooth device the data keeps coming from the inputstream and the graphic continues being generated.
I need the data and the graphic to stop when I turn off the bluetooth device.
I am using Java.
Every InputStream has a close() method that should do exactly what you need ... if you can detect that the device is turned off, that is.
The docs on this.
Reference link : Closing java InputStream
which resolved my problem too.
Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
} finally {
try {
fis.close();
fis=null;
} catch (IOException ioex) {
//omitted.
}
}
I've been trying to do this on my own for the past couple hours and am kinda losing it a little.
All I want to do is open a file, read it and display it to the console; that's it.
I'm using eclipse to develop for android 2.3.3.
I have tried using a bunch of different ways with code that I have found here, and on other sites. Here is what I have now and how its all called:
In the OnCreate function:
setContentView(new TestMap(this));
The testMap class:
TestMap(Context context){
super(context);
// might need to be on the panel class
loadTileFile("worldonelayout.txt", context);
in the same class:
private void loadTileFile (String filename, Context context){
FileInputStream input = null;
InputStreamReader reader = null;
char[] inputBuffer = new char[256];
String data = null;
try {
input = context.openFileInput("worldonelayout.txt");
reader = new InputStreamReader(input);
reader.read(inputBuffer);
data = new String(inputBuffer);
System.out.println(data);
Toast.makeText(context, "Text read", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(context, "Text not read", Toast.LENGTH_SHORT).show();
} finally {
try {
input.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
This code doesnt work. It always hits the exception.
"/data/data/com.name.somethingiremoved/files/worldonelayout.txt (No such file or directory)".
This happens at the first CATCH. BTW my file is in the root directory: Documents\Eclipse\workspace\project\worldonelayout.txt. I can also see the file in the browser on the left
From what I have seen here and on other sites, it is something to do with the Context class being derived from the Activity? I don't want to have this code in the same class as my activity. Is there a way round this?
If you need anything more from me, let me know.
The open file is looking for a file on the phone's file system, not on the computer's. Its telling you exactly where it expects to find it - on the phone under /data/data/com.name.somethingiremoved/files/worldonelayout.txt
I have a client application program that has 10+ classes each with 100+ components that need to be kept track of. When the program is run the user inputs numbers, selects items, toogles checkboxes, etc. I need to come up with a way to save all of the data input when the program is closed and have the capability of when the program is run again grab all the data from a previous time being run.
I have looked into Serialization but some of the things I need saved are not serializable so that didn't work. I have also looked into SingleFrameApplication and session storage but only in vain.
Writing to a file would cause the need for hours of tedious coding and would probably be inefficient. Does anyone have any ideas of how else I could tackle this hairy beast of a problem?
Update:
Doing what #home suggest I did the following:
public Main() throws FileNotFoundException {
initComponents();
//read the file
Read();
//...
}
private void formWindowClosing(java.awt.event.WindowEvent evt) {
try {
//write to the file, the program is closing
Write();
} catch (FileNotFoundException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void Read() throws FileNotFoundException {
try{
XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream("test.xml")));
//set the JTabbedPane to what is in the file
tab = (JTabbedPane) decoder.readObject();
decoder.close();
}catch(Exception e){
//there was no test.xml file so create one
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("test.xml")));
encoder.writeObject(null);
encoder.close();
}
}
private void Write() throws FileNotFoundException {
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("test.xml")));
//clear all previous things in the file
encoder.flush();
//write the JTabbedPane into the file
encoder.writeObject(tab);
encoder.close();
}
After these changes all that pops up when I run the program is a blank JTabbedPane. Can anyone explain why this is the case?
If you simply want to serialize an object compatible with JavaBeans specification, look at XML Encoder and Decoder: http://download.oracle.com/javase/6/docs/api/java/beans/XMLEncoder.html, http://download.oracle.com/javase/6/docs/api/java/beans/XMLDecoder.html
EDIT: Tutorial here: http://java.sun.com/products/jfc/tsc/articles/persistence4/