I have now come up with my own solution to this problem, which is a semi-automatic means of saving Bundles to SharedPreferences. I say semi-automatic because, although saving the Bundle requires only one method, retrieving the data again and turning it back into a Bundle takes some work.
Here is the code to save the Bundle:
SharedPreferences save = getSharedPreferences(SAVE, MODE_PRIVATE);
Editor ed = save.edit();
saveBundle(ed, "", gameState);
/**
* Manually save a Bundle object to SharedPreferences.
* @param ed
* @param header
* @param gameState
*/
private void saveBundle(Editor ed, String header, Bundle gameState) {
Set<String> keySet = gameState.keySet();
Iterator<String> it = keySet.iterator();
while (it.hasNext()){
key = it.next();
o = gameState.get(key);
if (o == null){
ed.remove(header + key);
} else if (o instanceof Integer){
ed.putInt(header + key, (Integer) o);
} else if (o instanceof Long){
ed.putLong(header + key, (Long) o);
} else if (o instanceof Boolean){
ed.putBoolean(header + key, (Boolean) o);
} else if (o instanceof CharSequence){
ed.putString(header + key, ((CharSequence) o).toString());
} else if (o instanceof Bundle){
saveBundle(header + key, ((Bundle) o));
}
}
ed.commit();
}
Note that I have only written cases for the types I needed, but this should be easily adaptable if you have Bundles that also include other types.
This method will recursively save other Bundle objects stored inside the given Bundle. However, it will not work for Parcelable objects, so I had to alter my Parcelable objects to make them store themselves into a Bundle instead. Since Parcels and Bundles are pretty similar, this wasn't too hard. I think Bundles may also be slightly slower than Parcels, unfortunately.
I then wrote constructors in all of my previously-Parcelable objects to enable them to re-Bundle themselves from the data stored SharedPreferences. It's easy enough to reconstruct the keys to the data you need. Say you have the following data structure:
Bundle b {
KEY_X -> int x;
KEY_Y -> Bundle y {
KEY_Z -> int z;
}
}
These will be saved to SharedPreferences as follows:
KEY_X -> x
KEY_YKEY_Z -> z
It may not be the prettiest method in the world, but it works, and it cost me much less code than the alternative, since now my onSaveInstanceState method and my onPause methods use the same technique.