In the app control panel I found an error report that not only I can't reproduce, but also it make no sense to me.
This is the stacktrace:
java.lang.ClassCastException: java.lang.Object[] cannot be cast to ohm.quickdice.entity.RollResult[]
at ohm.quickdice.activity.QuickDiceActivity.setupRollMenu(QuickDiceActivity.java:575)
at ohm.quickdice.activity.QuickDiceActivity.onCreateContextMenu(QuickDiceActivity.java:459)
at android.view.View.createContextMenu(View.java:6229)
at com.android.internal.view.menu.ContextMenuBuilder.show(ContextMenuBuilder.java:81)
at com.android.internal.policy.impl.PhoneWindow$DecorView.showContextMenuForChild(PhoneWindow.java:2292)
at android.view.ViewGroup.showContextMenuForChild(ViewGroup.java:564)
at android.view.ViewGroup.showContextMenuForChild(ViewGroup.java:564)
at android.view.ViewGroup.showContextMenuForChild(ViewGroup.java:564)
at android.view.ViewGroup.showContextMenuForChild(ViewGroup.java:564)
at android.widget.AbsListView.performLongPress(AbsListView.java:2772)
at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:2717)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4514)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
An this is the code where the exception occour:
ArrayList<RollResult[]> resultList;
RollResult[] lastResult;
...
protected void setupRollMenu(int index, ContextMenu menu) {
RollResult[] rollItem;
RollResult[] nextItem;
RollResult mergedRoll;
if (index < 0) {
rollItem = lastResult;
} else {
rollItem = resultList.get(index);
}
if (index + 1 < resultList.size()) {
nextItem = resultList.get(index + 1); //This is row 575
} else {
nextItem = null;
}
...
I wonder how the instruction "nextItem = resultList.get(int);" can raise this exception since resultList is defined as ArrayList and nextItem is an object of type RollResult[]...
It may depend on how Android serialize and deserialize instance state data to bundles?
Here how the serialization is done:
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable(KEY_LAST_ROLL, lastResult);
outState.putSerializable(KEY_ROLL_LIST, resultList);
super.onSaveInstanceState(outState);
}
and this is the deserialization:
@SuppressWarnings("unchecked")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
Serializable tmp;
tmp = savedInstanceState.getSerializable(KEY_LAST_ROLL);
if (tmp instanceof RollResult[]) {
lastResult = (RollResult[])tmp;
}
tmp = savedInstanceState.getSerializable(KEY_ROLL_LIST);
if (tmp instanceof ArrayList<?>) {
resultList = (ArrayList<RollResult[]>)tmp;
}
}
if (lastResult == null) {
lastResult = new RollResult[0];
}
if (resultList == null) {
resultList = new ArrayList<RollResult[]>();
}
}
Thanks.
Object
is being added to theArrayList
at runtime through reflection, unsafe casting or maybe (though I'm not sure on this) deserialization, the error will not be noticed until you try to assign thatObject
to a reference of the type it's supposed to be. If you can't reproduce it, maybe an old version stored an incorrectArrayList
on their end. – Jacob Raihle Aug 27 '12 at 12:52