我需要在持久性存储中存储一个复杂的自定义对象,以便在我的应用中保存用户的游戏进度。该对象和该对象中的每个对象都实现了 Serializable
我调用使用加载和保存方法在 Activity 之间传递对象。我还调用了 Save
方法 onStop()
来在应用程序关闭/销毁时保存对象。它工作正常。
public static Game Load(Context context){
try{
FileInputStream fis = context.openFileInput("player1.data");
ObjectInputStream is = new ObjectInputStream(fis);
Game game = (Game) is.readObject();
is.close();
fis.close();
return game;
}catch (Exception e){
Log.e("#Load", "creating new game - \n" + e.toString());
Game newGame = new Game();
return newGame;
}
}
public static void Save(Context context,Game game){
try{
FileOutputStream fos = context.getApplicationContext().openFileOutput("player1.data", Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(game);
os.close();
fos.close();
}catch (Exception e){
Log.e("#Save", "Failed to save - \n" + e.toString());
}
}
但是,如果应用程序被强制关闭或关闭并销毁,Game
对象就会变得困惑。重新启动时,应用程序将加载保存在 onStop()
中的 game
,但是当 game
对象被用户更改/交互时通过该应用程序,我的应用程序强制关闭,并在手机屏幕上显示“意外停止”消息。通过查看日志,我知道当 Game
对象在强制关闭/销毁后在启动时加载时,Load
方法返回 game
而不是 newGame
,因此强制关闭之间的保存/加载过程以某种方式搞砸了。
在日志中,我看到了这个:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
因此,我被引导相信使用 Serializable
时发生了一些奇怪的事情,或者我错误地写入了持久性存储。
我的问题:您是否发现我的代码存在任何根本性错误? (请记住,此代码确实有效,只是在 Force Close 情况下不起作用)
有人告诉我为了我的目的考虑使用 gson/JSON
(?);这种方法会比 Serializable
有更好的结果吗?我该如何使用它?
更新:似乎发生强制停止时,没有调用任何方法 - 包括 onDestroy()
和 onStop()
。如果是这种情况,那么为什么我的应用程序没有返回 newGame
?在 Force Closing 时查看日志,一条消息说“onSavedInstance not called”,这是什么?
我觉得我应该完全避免 Serializable
...
onCreate fragment
Game game;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
game = LoadGame.Load(this); //LoadGame is the class which contains Save,Load methods
@Override
protected void onStop() {
LoadGame.Save(this,game);
super.onStop();
}
最佳答案
提示,序列化很棒,我一直在使用它,问题是,您实际上是在实际遇到问题的线程上进行保存,您是否期待对 onStop()
的神奇调用?所以要么
您在不同的线程上定期调用您的保存方法,因此无论发生什么,它都会继续保存。-毕竟这是一个游戏-
您可以在您的代码中添加一个 try/catch 并捕获某些异常并在不同的线程上手动调用一个保存方法,那么您需要病态的封装。这可能无法很好地为您服务,因为无法捕获诸如
noSuchMethod
等错误,因此可能会发生强制关闭
任您选择。
关于java - 将可序列化对象保存在持久存储中(android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31215882/