Reputation: 97
My projects up until never needed data saved so this is the first time i have ever saved data. What i am trying to do is save data from an array list thats based off a class. Ive seen several people ask this with several different answers but i seem to be missing something. This is what the code is stripped down after all my attempts. Im hoping someone can help me on what to do for saving and loading with this info. Almost forgot this is a profile save of the app so there can be more then one file if the user chooses to.
//in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
//in java file
private ArrayList<otherclass> otherClass=new ArrayList<otherclass>();
class saveData
{
static private final int version=101002;
private String title;
private int[] Int1=new int[3];
private int[] Int2=new int[3];
private int[] Int3=new int[3];
private int Int;
}
class otherclass
{
//all the data goes here to similar named variables
}
Upvotes: 0
Views: 138
Reputation: 351
One way is to have the class you are adding to the ArrayList implement serializable. If your class is only made up of objects that also implement serializable then you are done (this is most likely the case), just add implements Serializable like this:
public class myClass implements Serializable {
Otherwise you will need to add the two below methods to your class
private void writeObject(java.io.ObjectOutputStream out) throws IOException
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
Add implements Serialible lets ObjectOutStream know that it can serialize your data for storage:
Then, you can implement the below methods to save and open your data, see comments for what each step does...
void saveArray(String filename, ArrayList<myClass> arrayToSave) {
FileOutputStream fos; //creates a file output stream to save your data
ObjectOutputStream oos; //creates an object output stream to serialize your data
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE); //creates and opens file with the specified filename, Context.MODE_PRIVATE limits its visibility to your app, other modes are available
oos = new ObjectOutputStream(fos); //connects object output to file output
oos.writeObject(arrayToSave); //writes the object to the file
}
catch (FileNotFoundException e) {
//handle file not found
}
catch (IOException e) {
}
//handle I/O execption
oos.close(); //close object output stream
fos.close(); //close file output stream
}
ArrayList<myClass> openArray (String filename) {
ArrayList<myClass> array = null; //create ArrayList
FileInputStream fis; //create fileinput stream
ObjectInputStream ois; //create objet input stream
try {
fis = openFileInput(filename); //open file stream
ois = new ObjectInputStream(fis); //open object stream
array = (ArrayList<myClass>)ois.readObject(); //create object from stream
}
catch (Exception e) {
System.out.println(e.toString());
}
ois.close(); //close objectinput stream
fis.close(); //close fileinput stream
return array;
}
Finally, both of the file input/output streams can be wrapped in a bufferedinputstream / bufferedoutput stream, but I have found with small files it doesn't affect performance much. That could be accomplished by
BufferedInputStream bufIn = new BufferedInputStream(new FileInputStream("file.java"));
BufferedOutputStream bufOut = new BufferedOutputStream(new FileInputStream("file.java"));
okay, below is a full activity file to demostrate this and has been tested with version 2.1...the only thing you need to change is the package name to match your project...note that this changes the variables in saveData to package from private, if you want to keep them private, which you probably should, you need to implement setters/getters, but the below code should help you understand saving/loading objects...
package youpackage.name.myapp;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
class saveData implements Serializable {
private static final long serialVersionUID = 1L;
private final int version = 101002;
String title;
int[] Int1 = new int[3];
int[] Int2 = new int[3];
int[] Int3 = new int[3];
int Int;
}
public class MyAppActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println("This next line creates instance of class to save");
saveData mySaveData = new saveData();
System.out.println("This next line sets the title...");
mySaveData.title = "accept my answer...";
ArrayList<saveData> myArrayList = new ArrayList<saveData>();
System.out.println("This next line adds the object to the ArrayList");
myArrayList.add(mySaveData);
System.out.println("This next line saves the arraylist");
saveArray("myFilename", myArrayList);
System.out.println("This next line loads the arraylist back...");
ArrayList<saveData> retrieveArrayList = openArray("myFilename");
if (retrieveArrayList.size() > 0) {
saveData retrievedSaveData = retrieveArrayList.get(0);
System.out.println("if successful, the title set above will appear...");
System.out.println("if save/retrieve works, then " + retrievedSaveData.title);
}
else {
System.out.println("it did not work");
}
}
void saveArray(String filename, ArrayList<saveData> arrayToSave) {
FileOutputStream fos;
ObjectOutputStream oos;
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(arrayToSave);
oos.close();
fos.close();
} catch (Exception e) {
System.out.println(e.toString());
}
}
ArrayList<saveData> openArray (String filename) {
ArrayList<saveData> array = null;
FileInputStream fis;
ObjectInputStream ois;
try {
fis = openFileInput(filename);
ois = new ObjectInputStream(fis);
array = (ArrayList<saveData>)ois.readObject();
ois.close();
fis.close();
} catch (Exception e) {
System.out.println(e.toString());
}
return array;
}
}
As I mentioned in my last post, the below updated methods for load and save improve the performance...
void saveArray2(String filename, ArrayList<saveData> arrayToSave) {
try {
BufferedOutputStream bos = new BufferedOutputStream(openFileOutput(filename, Context.MODE_PRIVATE),8000);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(arrayToSave);
oos.close();
} catch (Exception e) {
System.out.println(e.toString());
}
}
ArrayList<saveData> openArray2 (String filename) {
ArrayList<saveData> array = null;
try {
BufferedInputStream bufIn = new BufferedInputStream(openFileInput(filename),8000);
ObjectInputStream ois = new ObjectInputStream(bufIn);
array = (ArrayList<saveData>)ois.readObject();
ois.close();
} catch (Exception e) {
System.out.println(e.toString());
}
return array;
}
Upvotes: 2
Reputation: 12721
I just changed your private members to public ones. it you don't want that you'll need getters and setters for the values. also i don't know what you want with the final static version member... but heres a good approach:
class containing the data
class otherClass {
static private final int version=101002;
public String title;
public int[] Int1=new int[3];
public int[] Int2=new int[3];
public int[] Int3=new int[3];
public int Int;
}
class to read/write the data
class saveData {
public boolean write(ArrayList<otherClass> list, String fileName) {
try {
FileutputStream fos = new FileOutputStream(fileName);
DataOutputStream dos = new DataOutputStream(fos);
final int length = list.size();
for (int i = 0; i < length; i++) {
otherClass item = list.get(i);
dos.writeUTF(item.title);
dos.writeInt(item.Int1[0]);
dos.writeInt(item.Int1[1]);
dos.writeInt(item.Int1[2]);
dos.writeInt(item.Int2[0]);
dos.writeInt(item.Int2[1]);
dos.writeInt(item.Int2[2]);
dos.writeInt(item.Int3[0]);
dos.writeInt(item.Int3[1]);
dos.writeInt(item.Int3[2]);
dos.writeInt(item.Int);
}
dos.close();
fos.close();
return true;
} catch (IOException e) {
return false;
}
}
public ArrayList<otherClass> read(String fileName) {
try {
FileInputStream fos = new FileInputStream(fileName):
DataInputStream dis = new DataInputStream(fis);
ArrayList<otherClass> list = new ArrayList<otherClass>();
while (dis.available() > 0) {
otherClass item = new otherClass();
item.title = dis.readUTF();
item.Int1[0] = dis.readInt();
item.Int1[1] = dis.readInt();
item.Int1[2] = dis.readInt();
item.Int2[0] = dis.readInt();
item.Int2[1] = dis.readInt();
item.Int2[2] = dis.readInt();
item.Int3[0] = dis.readInt();
item.Int3[1] = dis.readInt();
item.Int3[2] = dis.readInt();
item.Int = dis.readInt();
list.add(item);
}
return list;
} catch (IOException e) {
return null;
}
}
}
example usage
saveData.write(list, "someFile");
list = saveData.read("someFile");
Upvotes: 1