在Android中序列化抛出异常

时间:2013-10-30 11:32:23

标签: java android android-intent

我正在开发一个Android项目,我希望序列化一个类对象。我环顾四周如何做到这一点,我发现有几种解决方案。尝试了以下解决方案:

       public static byte[] toByteArray(Object obj) throws IOException {
        byte[] bytes = null;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
        } finally {
            if (oos != null) {
             Log.i(TAG, "not null");
                oos.close();
            }
            if (bos != null) {
                bos.close();
             Log.i(TAG, "not null");
            }
        }
        return bytes;
    }

我正在尝试序列化的对象如下定义:

         // ObjectInfo struct definition
           public class ObjectInfo implements java.io.Serializable
 {
        public int ObjectXCor;
        public int ObjectYCor;
        public int ObjectMass;

        //Constructor
        public ObjectInfo(){
            ObjectMass = 0;
            ObjectXCor = 0;
            ObjectYCor = 0;
        }
    };

    // ObjectInfo struct definition
    public class SensorDataStruct implements java.io.Serializable
    {
        public int PingData;
        public int IRData;
        public int ForceData;
        public int CompassData;

        //Constructor
        public SensorDataStruct(){
            CompassData = 0;
            ForceData = 0;
            IRData = 0;
            PingData = 0; 
        }
    };

    // ObjectInfo struct definition
    public class CommStruct implements java.io.Serializable
   {
            public ObjectInfo VisionData;
            public SensorDataStruct SensorData;

            //Constructor
            public CommStruct(){
                 // Call constructors
                 VisionData = new ObjectInfo();
                 SensorData = new SensorDataStruct();
            }
    };

在onClick方法中调用toByteArray方法,如下所示:

 try {
    Log.i(TAG, "==== trying to serialize ====");
    communicationmoduleUDSB.toByteArray(CMUSB.SendPacket);
} 
catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    Log.i(TAG, "Failed to serialize!");
}

当我按下附加到on onClick方法的按钮时,我发现异常被抛出。但我不知道为什么,有没有人有想法?欢迎所有建议!

发生异常时在Catlog中打印的跟踪(还添加了方法的第一个打印件(非空):

10-30 12:21:15.474: I/CommunicatorApp:(12338): ==== trying to serialize ====
10-30 12:21:15.554: I/(12338): not null
10-30 12:21:15.554: I/(12338): not null
10-30 12:21:15.554: W/System.err(12338): java.io.NotSerializableException: com.example.communicationmodulebase.Server
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
10-30 12:21:15.564: W/System.err(12338):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
10-30 12:21:15.574: W/System.err(12338):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
10-30 12:21:15.574: W/System.err(12338):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
10-30 12:21:15.574: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
10-30 12:21:15.594: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
10-30 12:21:15.604: W/System.err(12338):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
10-30 12:21:15.604: W/System.err(12338):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
10-30 12:21:15.604: W/System.err(12338):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
10-30 12:21:15.604: W/System.err(12338):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
10-30 12:21:15.614: W/System.err(12338):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
10-30 12:21:15.614: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
10-30 12:21:15.614: W/System.err(12338):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
10-30 12:21:15.614: W/System.err(12338):    at com.example.communicationmoduleUSB.communicationmoduleUDSB.toByteArray(communicationmoduleUDSB.java:121)
10-30 12:21:15.614: W/System.err(12338):    at com.example.communicationmodule.MainActivity$1.onClick(MainActivity.java:41)
10-30 12:21:15.614: W/System.err(12338):    at android.view.View.performClick(View.java:4162)
10-30 12:21:15.624: W/System.err(12338):    at android.view.View$PerformClick.run(View.java:17082)
10-30 12:21:15.624: W/System.err(12338):    at android.os.Handler.handleCallback(Handler.java:615)
10-30 12:21:15.624: W/System.err(12338):    at android.os.Handler.dispatchMessage(Handler.java:92)
10-30 12:21:15.624: W/System.err(12338):    at android.os.Looper.loop(Looper.java:137)
10-30 12:21:15.634: W/System.err(12338):    at android.app.ActivityThread.main(ActivityThread.java:4867)
10-30 12:21:15.634: W/System.err(12338):    at java.lang.reflect.Method.invokeNative(Native Method)
10-30 12:21:15.634: W/System.err(12338):    at java.lang.reflect.Method.invoke(Method.java:511)
10-30 12:21:15.634: W/System.err(12338):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
10-30 12:21:15.644: W/System.err(12338):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
10-30 12:21:15.644: W/System.err(12338):    at dalvik.system.NativeStart.main(Native Method)
10-30 12:21:15.644: I/CommunicatorApp:(12338): Failed to serialize!

更新

有关更多信息,请参阅CommunicationModule和CommunicationModuleUSB类。

CommunicatoionModule (Base class):
package com.example.communicationmodulebaseclass;


public class communicationmodule implements java.io.Serializable
{

     // ObjectInfo struct definition
    public class ObjectInfo implements java.io.Serializable
{
        public int ObjectXCor;
        public int ObjectYCor;
        public int ObjectMass;

        //Constructor
        public ObjectInfo(){
            ObjectMass = 0;
            ObjectXCor = 0;
            ObjectYCor = 0;
        }
    };

    // ObjectInfo struct definition
    public class SensorDataStruct implements java.io.Serializable
{
        public int PingData;
        public int IRData;
        public int ForceData;
        public int CompassData;

        //Constructor
        public SensorDataStruct(){
            CompassData = 0;
            ForceData = 0;
            IRData = 0;
            PingData = 0; 
        }
    };

    // ObjectInfo struct definition
    public class CommStruct implements java.io.Serializable
{
            public ObjectInfo VisionData;
            public SensorDataStruct SensorData;

            //Constructor
            public CommStruct(){
                 // Call constructors
                 VisionData = new ObjectInfo();
                 SensorData = new SensorDataStruct();
            }
    };

    public CommStruct SendPacket;
    public CommStruct RecievePacket;
    public ObjectInfo  Test;

    public communicationmodule(){

    }

    public void SendBuffer(){

    }

    public void Send(){

    }

    public void RecieveBuffer(){

    }

    public void Recieve(){

    }
}

扩展CommuncationModule类的CommuncationModuleUSB类

package com.example.communicationmoduleUSB;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

import android.os.*;
import android.util.Log;

import com.example.communicationmodulebase.Server;
import com.example.communicationmodulebaseclass.communicationmodule;
import com.example.communicationmodulebaseclass.communicationmodule.CommStruct;
import com.example.communicationmodulebaseclass.communicationmodule.ObjectInfo;

public class communicationmoduleUDSB extends communicationmodule  {

    private static final String TAG = null;
    public byte ArrayRecieved[] = new byte[2];
    public byte ArrayOutput[] = new byte[2];
    public boolean UseStructFunction = true; 


    // Create TCP server (based on  MicroBridge LightWeight Server). 
    // Note: This Server runs in a separate thread.
    Server server = null;

    public communicationmoduleUDSB(){
        SendPacket = new CommStruct();
        RecievePacket = new CommStruct();
        Test = new ObjectInfo();

        RecievePacket.SensorData.CompassData = 0;
        SendPacket.SensorData.CompassData = 0;

        //SendPacket = RecievePacket;

         // Create TCP server (based on  MicroBridge LightWeight Server)
        try
        {
            server = new Server(4568); //Use the same port number used in ADK Main Board firmware
            server.start();     

        } catch (IOException e)
        {
            Log.e("Seeeduino ADK", "Unable to start TCP server", e);

        }


        server.addListener(new com.example.communicationmodulebase.AbstractServerListener() {

            // Recieve handler example function
            // Recieves data and sends it back
            @Override
            public void onReceive(com.example.communicationmodulebase.Client client, byte[] data)
            {       

                if(UseStructFunction){

                    // Event handler for recieving data, the size of structs    
                    //if (data.length < 10){
                    //  return;
                    //}

                    // Send CommStruct
                    Send();

                }
                else{
                        // Event handler for recieving data, the size of the desired data to
                        // be recieved
                        if (data.length < 10){
                            return;
                        }


                        //For this example convert recieved data to char array before sending back
                        String str = new String(data); //using the platform's default charset
                        char[] chars = str.toCharArray(); 

                        //Send buffer function, send data back
                        SendBuffer(chars, 28);
                }
            }
        });  


    }


    // Send buffer function
    public void SendBuffer(char Buffer[], int Size){

           // Declare and init a byte array
           byte ByteBuffer[] = new byte[Size];

           // Fill byte array
           for(int i=0; i < Size; i++){
               ByteBuffer[i] = (byte) Buffer[i];
           }

            try
            {
                // Send byte array
                server.send(ByteBuffer);

            } 
            catch (IOException e)
            {
                Log.e("USBCommunicator", "problem sending TCP message", e);
            }   
    }

       public static byte[] toByteArray(CommStruct obj) throws IOException {
            byte[] bytes = null;
            ByteArrayOutputStream bos = null;
            ObjectOutputStream oos = null;
            try {
                bos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(bos);
                oos.writeObject(obj);
                oos.flush();
                bytes = bos.toByteArray();
            } finally {
                if (oos != null) {
                 Log.i(TAG, "not null");
                    oos.close();
                }
                if (bos != null) {
                    bos.close();
                 Log.i(TAG, "not null");
                }
            }
            return bytes;
        }

    // Send struct function
    public void Send(){     

        try
        {           
            // First convert the CommStruct to a byte array
            // Then send the byte array
            server.send(toByteArray(SendPacket));

        } 
        catch (IOException e)
        {
            Log.e("USBCommunicator", "problem sending TCP message", e);
        }   
    }
    }

1 个答案:

答案 0 :(得分:1)

您正在尝试序列化CMUSB.SendPacket,这很可能属于com.example.communicationmodulebase.Server类型。此类型不可序列化,因此异常发生在行oos.writeObject(obj);

你应该序列化其他一些类。我不确定这个类的功能,但你应该查看这个类所持有的数据(重新创建类所需的数据),而不是这个类本身的对象。


作为旁边的注释,可序列化的类应该定义这个常量:

private static final long serialVersionUID = -5003427037057257659L;

每个人都有唯一的编号。这将确保它们始终被正确序列化和反序列化。点击此处查看更多信息:What is a serialVersionUID and why should I use it?

相关问题