我需要将一个int[][]保存到Bundle以便在onSaveInstanceState()期间保存并在onCreate()上恢复。 首先,我决定让它直截了当,将2D阵列压平成1D并在负载时展开。 一切都很好。
我决定找一个更简单的方法。 我被告知2D数组是可序列化的,所以我做了这样的事情:
public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putSerializable("CELLS_STATE",universe.getUniverse()); super.onSaveInstanceState(savedInstanceState); }//onSaveInstanceState其中universe.getUniverse()返回int[][] 。
在onCreate()重新加载:
if(savedInstanceState != null) {//save data exists, reload it universe = new Universe( (int[][])savedInstanceState.getSerializable("CELLS_STATE") ); }这是捕获。 如果我运行程序并转动手机以使屏幕改变方向,它会完全加载。
但是 ,当我按下主页按钮,然后使用应用程序杀手(在我的情况下是电池医生)杀死应用程序并尝试从菜单再次启动它时,它会崩溃,我只能从第二次尝试启动它,并且保存的状态丢失了。 在该崩溃时给出的错误指向我在上面指定的getSerializable行,它是:
java.lang.ClassCastException: java.lang.Object[] cannot be cast to int[][]这让我很困惑。 因此,无论何时屏幕方向发生变化(可能还有其他内容), getSerializable返回可以getSerializable转换为2D数组的内容(可能是Serializable )。 但是每当应用程序被杀死时,它都会返回无法转换的内容。 是什么导致了这种奇怪的行为,有没有办法绕过它?
I need to save an int[][] into a Bundle so it could be saved during onSaveInstanceState() and restored on onCreate(). First, I've decided to make it straightforward and flatten a 2D array into 1D and deflatten on load. It all worked fine.
I've decided to find an easier way. I was told that 2D arrays are serializable, so I made it something like this:
public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putSerializable("CELLS_STATE",universe.getUniverse()); super.onSaveInstanceState(savedInstanceState); }//onSaveInstanceStatewhere universe.getUniverse() returns an int[][].
Reloading within onCreate():
if(savedInstanceState != null) {//save data exists, reload it universe = new Universe( (int[][])savedInstanceState.getSerializable("CELLS_STATE") ); }Here's the catch. If I run the program and turn my phone so the screen changes orientation, it loads perfectly fine.
But, when I press the home button and then kill the app using an app killer (in my case it is Battery Doctor) and try to start it again from the menu, it crashes and I can launch it only from the second attempt, and the saved state is lost. The error that is given on that crash points to the line with getSerializable I've specified above, and it is:
java.lang.ClassCastException: java.lang.Object[] cannot be cast to int[][]This confuses me. So, whenever screen orientation changes (and maybe something else), getSerializable returns something that can be cast to a 2D array (probably, Serializable). But whenever the app is killed, it returns something that cannot be cast. What causes such a strange behaviour and is there a way to bypass it?
最满意答案
是什么导致了这种奇怪的行为......?
看来这是Parcel实现中的一个错误,我建议阅读第6条评论,其中包含对bug性质的非常好的解释。
..有没有办法绕过它?
以下代码应该工作:
if (savedInstanceState != null) { final Object[] objects = savedInstanceState.getSerializable("CELLS_STATE"); final int[][] cells = new int[objects.length][]; for (int i = 0; i < objects.length; i++) { cells[i] = (int[]) objects[i]; } universe = new Universe(cells); }What causes such a strange behavior...?
It appears that this is a bug in the Parcel's implementation, I recommend to read comment #6 which contains the very good explanation of bug's nature.
.. and is there a way to bypass it?
The following code should work:
if (savedInstanceState != null) { final Object[] objects = savedInstanceState.getSerializable("CELLS_STATE"); final int[][] cells = new int[objects.length][]; for (int i = 0; i < objects.length; i++) { cells[i] = (int[]) objects[i]; } universe = new Universe(cells); }更多推荐
发布评论