Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException occurs in onRestoreInstanceState

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
like image 482
chris Avatar asked Jul 01 '12 05:07

chris


2 Answers

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.

like image 62
Nik Avatar answered Sep 24 '22 12:09

Nik


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.

like image 25
acj Avatar answered Sep 24 '22 12:09

acj