私は今、この問題に対する独自の解決策を考え出しました。これは、バンドルをSharedPreferencesに保存する半自動の手段です。バンドルの保存に必要なメソッドは1つだけですが、データを再度取得してバンドルに戻すには多少の作業が必要になるため、半自動と言います。
バンドルを保存するコードは次のとおりです。
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();
}
必要なタイプのケースのみを記述していることに注意してください。ただし、他のタイプも含むバンドルがある場合、これは簡単に適応できるはずです。
このメソッドは、指定されたバンドル内に格納されている他のバンドルオブジェクトを再帰的に保存します。ただし、Parcelableオブジェクトでは機能しないため、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メソッドが同じ手法を使用しているため、他のメソッドよりもはるかに少ないコードで済みます。