ClassCastException occurs in onRestoreInstanceState
Asked Answered
T

2

8

ClassCastException occurs randomly to restore Vector in onRestoreInstanceState(). Generally restoring vector is finished well, but sometimes exception occurs.

I think it happens when activity is went to background and destroyed but I'm not sure.

Any ideas? Thank you.

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);
}

ADDED:

I forgot to attach exception log. That is

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Stack
Trin answered 1/7, 2012 at 5:57 Comment(4)
I suggest that you rewrite your onRestoreInstanceState method as follows: 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()); } Then you can at least see what you're getting back. (Sorry for posting code in a comment; I don't want to post this as an answer).Bertolde
I thought that way, but I really want to know what mechanism makes this case. I added exception log and I don't know why object type is changed to ArrayList.Trin
By any chance does your activity superclass override onSaveInstanceState? I'm wondering if you're using the "locationInfos" key anywhere else in your code. (P.S. in any event, you should reorganize your onRestoreInstanceState code so that it only calls getSerializable() once.)Bertolde
@user1285975 this happens to me too, did you solve it? When rotating the screen, the deserialization and casting in onRestoreInstanceState works ok. When the Activity is removed from memory, it throws ClassCastException in onRestoreInstanceState.Tactician
U
5

I use next code to restore Vector:

objects = new Vector<Object>((Collection<Object>) state.getSerializable(EXTRA_OBJECTS));

It prevents java.lang.ClassCastException and saves elements order.

To restore Stack, you can use next code:

stack = new Stack<Object>();
stack.addAll((Collection<Object>) state.getSerializable(EXTRA_STACK));

It works due to Vector, Stack, ArrayList are extending Collection, and you can cast your serialized object to Collection and pass to Stack or Vector addAll() method.

Uriniferous answered 18/2, 2013 at 5:52 Comment(0)
V
5

This typically happens when the activity has been destroyed because of memory pressure. The bundle passed to onRestoreInstanceState seems to retain an instance of the base class (ArrayList in this case).

You may be able to reproduce the issue by tweaking the developer options:

  1. Go to Settings | Developer Options
  2. Check the box for "Don't keep activities"

Now your activity will be destroyed immediately after you leave it. Launching the activity in question, pressing the Home button, and then switching back to your app should trigger the ClassCastException.

In the meantime, Ted Hopp's suggestion to use

if (saved instanceof Stack) {
    ....
}

should avoid crashing the app.

Vertumnus answered 1/8, 2012 at 14:24 Comment(1)
I still don't know the mechanism that saved value exist in the bundle, but type is changed.Trin
U
5

I use next code to restore Vector:

objects = new Vector<Object>((Collection<Object>) state.getSerializable(EXTRA_OBJECTS));

It prevents java.lang.ClassCastException and saves elements order.

To restore Stack, you can use next code:

stack = new Stack<Object>();
stack.addAll((Collection<Object>) state.getSerializable(EXTRA_STACK));

It works due to Vector, Stack, ArrayList are extending Collection, and you can cast your serialized object to Collection and pass to Stack or Vector addAll() method.

Uriniferous answered 18/2, 2013 at 5:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.