ClassCastException 发生在 onRestoreInstanceState
Posted
技术标签:
【中文标题】ClassCastException 发生在 onRestoreInstanceState【英文标题】:ClassCastException occurs in onRestoreInstanceState 【发布时间】:2012-07-02 01:19:14 【问题描述】:ClassCastException 随机发生以在 onRestoreInstanceState() 中恢复 Vector。 一般恢复向量都可以很好地完成,但有时会出现异常。
我认为当活动进入后台并被销毁时会发生这种情况,但我不确定。
有什么想法吗?谢谢。
Stack<LocationInfo> mLocationInfoVector;
@Override
protected void onSaveInstanceState(Bundle outState)
outState.putSerializable("locationInfos", mLocationInfoVector);
super.onSaveInstanceState(outState);
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
if (savedInstanceState.getSerializable("locationInfos") != null)
@SuppressWarnings("unchecked")
mLocationInfoVector= (Stack<LocationInfo>) savedInstanceState.getSerializable("locationInfos");
super.onRestoreInstanceState(savedInstanceState);
添加:
我忘了附上异常日志。 那是
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Stack
【问题讨论】:
我建议你重写你的onRestoreInstanceState
方法如下:Object saved = savedInstanceState.getSerializable("locationInfos"); if (saved instanceof Stack) mLocationInfoVector = (Stack<LocationInfo>) saved; else if (saved != null) Log.e("RestoreBug", "Restored object class: " + saved.getClass().getName());
然后你至少可以看到你得到了什么。 (很抱歉在评论中发布代码;我不想将此作为答案发布)。
我是这么想的,但我真的很想知道是什么机制造成了这种情况。我添加了异常日志,不知道为什么对象类型改为ArrayList。
您的活动超类是否会覆盖onSaveInstanceState
?我想知道您是否在代码中的其他任何地方使用 "locationInfos"
键。 (PS 在任何情况下,您都应该重新组织您的 onRestoreInstanceState
代码,使其只调用一次 getSerializable()
。)
@user1285975 这也发生在我身上,你解决了吗?旋转屏幕时,onRestoreInstanceState 中的反序列化和强制转换工作正常。当 Activity 从内存中移除时,它会在 onRestoreInstanceState 中抛出 ClassCastException。
【参考方案1】:
我使用下一个代码来恢复 Vector:
objects = new Vector<Object>((Collection<Object>) state.getSerializable(EXTRA_OBJECTS));
它可以防止 java.lang.ClassCastException 并保存元素顺序。
要恢复堆栈,您可以使用下一个代码:
stack = new Stack<Object>();
stack.addAll((Collection<Object>) state.getSerializable(EXTRA_STACK));
由于 Vector、Stack、ArrayList 是 Collection 的扩展,它可以工作,您可以将序列化的对象转换为 Collection 并传递给 Stack 或 Vector addAll() 方法。
【讨论】:
【参考方案2】:这通常发生在 Activity 因内存压力而被销毁时。传递给 onRestoreInstanceState 的包似乎保留了基类的一个实例(在这种情况下为ArrayList
)。
您可以通过调整开发者选项来重现该问题:
-
转到设置 |开发者选项
选中“不保留活动”复选框
现在您的活动将在您离开后立即销毁。启动有问题的 Activity,按下 Home 按钮,然后切换回您的应用程序应该会触发 ClassCastException
。
同时,Ted Hopp 建议使用
if (saved instanceof Stack)
....
应避免应用崩溃。
【讨论】:
我仍然不知道bundle中存在保存值的机制,但是类型改变了。以上是关于ClassCastException 发生在 onRestoreInstanceState的主要内容,如果未能解决你的问题,请参考以下文章
使用 Apache CXF 调用 SOAP API 时发生 ClassCastException
在 Wildfly 8.2 上重新部署后从 Infinispan 缓存读取时发生 ClassCastException
springboot读取redis发生java.lang.ClassCastException异常
当十进制为 0 时,DecimalFormat.parse() 的转换结果时发生 ClassCastException
当vectorized.execution.enabled 使用带有Hive 的ORC 文件格式时发生ClassCastException