Android Bundle和ClassCastException

时间:2012-06-24 23:28:48

标签: android classcastexception

我在自定义视图中有两个辅助方法,它们由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");
}

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

nWidthnHeight是静态int,表示原始分辨率。

然而,在蓝色的月亮中,我被赋予了ClassCastException。为什么呢?

从我的测试中看来,您可以将null投射到int[][],尽管这实际上并不是我的目标。 colorData是类型int[][],我从来没有在任何地方得到NullPointerException,因此除了将Serializable投射到int[][]并且仅偶尔投射,所以我可以告诉一切正常。

这是一个堆栈跟踪,虽然它在这种情况下没什么用处:

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)

2 个答案:

答案 0 :(得分:0)

Serializable界面如果充满缺陷,应尽可能避免,尤其是在Android中。从代码的外观来看,您只是临时将此对象传递给Bundle,因此可以重新创建一个Activity或其他组件,如果没有其他组件,序列化该对象将为这种临时需求提供较差的性能。 / p>

如果您在onRetainNonConfigurationInstance()的上下文中,API getLastNonConfigurationInstance()及其对应的Activity将是一种更有效的传递该对象的方法。如果您使用的是Fragment API,请查看setRetainInstance()方法。

HTH

答案 1 :(得分:0)

对我来说,它看起来很奇怪,因为Java(多维)数组默认是可序列化的(或者我错了?)。但似乎至少在Android中,有些东西与此有所不同。

你总是应该使用Parcelable传递。实现起来有点乏味,但比Serializable更快......这是一个方法:Passing multidimensional array using Serializable