我现在想出了我自己的解决方案来解决这个问题,这是一种将 Bundles 保存到 SharedPreferences 的半自动方法。我说半自动是因为,虽然保存 Bundle 只需要一种方法,但再次检索数据并将其转回 Bundle 需要一些工作。
这是保存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();
}
请注意,我只为我需要的类型编写了案例,但是如果您有还包含其他类型的 Bundle,这应该很容易适应。
此方法将递归保存存储在给定 Bundle 中的其他 Bundle 对象。但是,它不适用于 Parcelable 对象,因此我必须更改我的 Parcelable 对象以使它们将自己存储到 Bundle 中。由于 Parcels 和 Bundles 非常相似,这并不难。不幸的是,我认为捆绑包也可能比包裹稍慢。
然后,我在所有以前的 Parcelable 对象中编写了构造函数,以使它们能够从存储的 SharedPreferences 数据中重新捆绑自己。重建所需数据的密钥很容易。假设您有以下数据结构:
Bundle b {
KEY_X -> int x;
KEY_Y -> Bundle y {
KEY_Z -> int z;
}
}
这些将按如下方式保存到 SharedPreferences:
KEY_X -> x
KEY_YKEY_Z -> z
它可能不是世界上最漂亮的方法,但它很有效,而且它比其他方法花费的代码少得多,因为现在我的 onSaveInstanceState 方法和我的 onPause 方法使用相同的技术。