简体   繁体   中英

Android Bundle and ClassCastException

I have two helper methods inside a custom View which are called by their Fragment:

public Bundle returnInstanceState() {
        Bundle state = new Bundle();
        state.putSerializable("colorData", colorData);
        return state;
}

public void loadInstanceState(Bundle savedInstanceState) {
    if(savedInstanceState.getSerializable("colorData") != null)
            colorData = (int[][]) savedInstanceState.getSerializable("colorData");
}

The lifecycle of colordata:

private int[][] colorData;

protected void onSizeChanged (int w, int h, int oldw, int oldh) 
{
    width = w;
    height = h;
    screen = new int[width*height];
    cellSize = 0;
    if(firstLoad && h!= 0 && w!=0)
    {

    if(nWidth>nHeight)
        colorData = new int[nWidth/(nHeight/170 - 1) + 1][170];
    else
            colorData = new int[nHeight/(nWidth/170 - 1) + 1][170];
        firstLoad = false;
    }
}

nWidth and nHeight are static int which represent the native resolution.

However once in a blue moon I am given a ClassCastException. Why?

From my tests it seems you can cast null to int[][] though thats not actually a goal of mine. colorData is type int[][] and I never get a NullPointerException anywhere so as far as I can tell everything works except the act of casting Serializable to int[][] and only occasionally.

Here is a stack trace, though it isn't of much use in this case:

java.lang.RuntimeException: Unable to start activity ComponentInfo{<MYPACKAGENAMEHERE>/<MYPACKAGENAMEHERE>.MusicVisualizerActivity}: java.lang.ClassCastException: [Ljava.lang.Object;
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1659)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1675)
    at android.app.ActivityThread.access$1500(ActivityThread.java:121)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3701)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: [Ljava.lang.Object;
    at <MYPACKAGENAMEHERE>.Visualization_Spectral$RenderView.loadInstanceState(Visualization_Spectral.java:95)
    at <MYPACKAGENAMEHERE>.Visualization_Spectral.onCreateView(Visualization_Spectral.java:46)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1810)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:501)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
    at android.app.Activity.performStart(Activity.java:3791)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1632)
    ... 11 more
java.lang.ClassCastException: [Ljava.lang.Object;
    at <MYPACKAGENAMEHERE>.Visualization_Spectral$RenderView.loadInstanceState(Visualization_Spectral.java:95)
    at <MYPACKAGENAMEHERE>.visualization.Visualization_Spectral.onCreateView(Visualization_Spectral.java:46)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1810)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:501)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
    at android.app.Activity.performStart(Activity.java:3791)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1632)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1675)
    at android.app.ActivityThread.access$1500(ActivityThread.java:121)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3701)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
    at dalvik.system.NativeStart.main(Native Method)

The Serializable interface if full of flaws and should be avoided whenever possible, especially in Android. From the looks of your code, your are only temporarily passing this object into a Bundle so an Activity or other component can be recreated and, if nothing else, serializing the object will provide poor performance for such a temporary need.

The API onRetainNonConfigurationInstance() and its counterpart getLastNonConfigurationInstance() will be a much more efficient method of passing that object around if you are in the context of an Activity . If you are using the Fragment APIs, take a look at the setRetainInstance() method as well.

HTH

For me it looks strange because Java (multidimensional) arrays are serializable by default (or am I wrong?). But it seems that, at least in Android, something is different with this.

You anyways should pass using Parcelable. It's somewhat tedious to implement, but faster than Serializable... Here is a howto: Passing multidimensional array using Serializable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM