我需要在持久存储中存储复杂的自定义对象,以便在我的应用中保存用户的游戏进度。该对象中的对象和每个对象都实现Serializable
我调用了使用加载和保存方法在活动之间传递对象。当应用程序关闭/销毁时,我还调用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
对象会混乱。重新启动时,应用程序将加载已保存game
的{{1}},但当用户通过应用程序更改/交互onStop()
对象时,我的应用程序将关闭“意外停止“在手机屏幕上显示消息。通过查看日志,我知道在强制关闭/销毁后,game
方法在启动时加载Game
对象时,Load
方法将返回game
而不是newGame
,所以在某种程度上,Force Close之间的保存/加载过程会混淆一些东西。
在日志中,我看到了:
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
?在强制关闭时查看日志,这条消息说“onSavedInstance没有被调用”,这是什么?
我觉得我应该完全避免Serializable
......
onCreate代码段
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();
}
答案 0 :(得分:1)
提示,序列化很棒我总是使用它,事实是,你实际上是在实际遇到问题的线程上保存,你是否期望对onStop()
进行神奇的调用?所以
您可以在不同的线程上定期调用您的保存方法,因此无论发生什么事情,它都会一直保存.-在所有游戏之后 -
您可以在代码中添加try / catch并捕获某些异常,并在不同的Thread上手动调用save方法,这样您需要生病的Encapsulation。这可能不适合您,因为noSuchMethod
等错误无法捕获,因此可能会发生强制关闭