I have an ArrayList
of custom, simple Serializable
objects I would like to cache to disk and read on re-launch. My data is very small, about 25 objects and at most 5 lists so I think SQLite would be overkill. In the iPhone world I would use NSKeyedArchiver
and NSKeyedUnarchiver
which works great. On Android I've attempted to do this with with a FileOutputStream
and ObjectOutputStream
and while the result is the same, the performance is terrible. Is there a better (read faster) way to cache small objects to the file system in Android?

- 15,409
- 15
- 81
- 150

- 5,074
- 3
- 34
- 35
-
Do you know which part is the performance hog? – Christopher Orr Jan 05 '10 at 03:55
3 Answers
For what it worth I cache some of my String data to disk using BufferedWriter/BufferedReader and it's very fast. Matter of fact it is faster than storing the same data to SharedPreferences. The code goes something like this (note that things happen faster when you provide buffer size)
final BufferedWriter out = new BufferedWriter(new FileWriter(file), 1024);
out.write(stuff);
out.close();

- 36,858
- 39
- 167
- 227
-
2Yeah, the problem is I want "stuff" to be my serialized objects which for whatever reason seems to be the issue. – Greg Martin Jan 06 '10 at 00:28
-
Well if your objects are simple enough you can overwrite readObject and writeObject – Bostone Jan 06 '10 at 01:46
-
So I ended up just writing the raw JSON text out to a file using this method and then re-parsing it when I launched. Since the JSON is small it seems to perform OK, though I'm still not completely happy with not being able to serialize my objects to disk. – Greg Martin Jan 12 '10 at 04:37
-
1There could be a lot going on behind the scenes with Serialization. I've usually found much better performance by using the Externalizable interface. You end up having to code a little more, but I've always seen a huge increase. This could be even more dramatic on a mobile device. http://stackoverflow.com/questions/817853/what-is-the-difference-between-serializable-and-externalizable-in-java – GrkEngineer Jul 08 '10 at 21:15
-
FileWritter always uses platform default encoding wich is not a good idea. I would prefer to use `new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),Charset.forName("UTF-8")));` instead. – Patrick Apr 28 '15 at 11:09
-
-
I found this to be almost the opposite. When using Jackson to serialize data and saving it in the SharedPreferences, running metrics on 100 read/writes vs a serialized object save to disk/read from disk, SharedPreferences were always faster. – AllDayAmazing Feb 29 '16 at 07:33
public class MyClass implements Serializable
{
private static final long serialVersionUID = 1L;
public String title;
public String startTime;
public String endTime;
public String day;
public boolean classEnabled;
public MyClass(String title, String startTime, boolean enable) {
this.title = title;
this.startTime = startTime;
this.classEnabled = enable;
}
public boolean saveObject(MyClass obj) {
final File suspend_f=new File(SerializationTest.cacheDir, "test");
FileOutputStream fos = null;
ObjectOutputStream oos = null;
boolean keep = true;
try {
fos = new FileOutputStream(suspend_f);
oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
} catch (Exception e) {
keep = false;
} finally {
try {
if (oos != null) oos.close();
if (fos != null) fos.close();
if (keep == false) suspend_f.delete();
} catch (Exception e) { /* do nothing */ }
}
return keep;
}
public MyClass getObject(Context c) {
final File suspend_f=new File(SerializationTest.cacheDir, "test");
MyClass simpleClass= null;
FileInputStream fis = null;
ObjectInputStream is = null;
try {
fis = new FileInputStream(suspend_f);
is = new ObjectInputStream(fis);
simpleClass = (MyClass) is.readObject();
} catch(Exception e) {
String val= e.getMessage();
} finally {
try {
if (fis != null) fis.close();
if (is != null) is.close();
} catch (Exception e) { }
}
return simpleClass;
}
and calling from activity
if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"MyCustomObject");
else
cacheDir= getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
MyClass m = new MyClass("umer", "asif", true);
boolean result = m.saveObject(m);
if(result)
Toast.makeText(this, "Saved object", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Error saving object", Toast.LENGTH_LONG).show();
MyClass m = new MyClass();
MyClass c = m.getObject(this);
if(c!= null)
Toast.makeText(this, "Retrieved object", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Error retrieving object", Toast.LENGTH_LONG).show();
dont forget to use write_external_storage permissions in manifest file.

- 5,093
- 30
- 32
It's hard to know without profiling but my guess is your poor performance is down to using ObjectOutputStream
. Have you tried writing your own writeObject(ObjectOutputStream)
and readObject(ObjectOutputStream)
methods as this may help performance.
You could use the traceview
tool to see exactly where the application is running slow. Have a look at this question for instructions on how to use traceview
.

- 1
- 1

- 190,537
- 57
- 313
- 299