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&lt;LocationInfo&gt;) 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

java.lang.ClassCastException 为啥?