2013-03-27 58 views
2

我正在嘗試在Java服務器和Android客戶端之間使用對象序列化套接字連接。嘗試通過此連接發送日曆對象時遇到問題。Android日曆序列化與Java不兼容6

日曆對象是由Java服務器發送並通過Android客戶端接收,但是我在logcat中得到錯誤信息:

java.lang.NullPointerException: expected receiver of type java.util.TimeZone, but got null

我意識到,這是不正確的反序列化。

我編寫此代碼示例重現錯誤:

Java服務器:

public class SerializeTest { 

    public static void main(String[] args) { 
     try { 

     ServerSocket serverSocket = new ServerSocket(49100); 
     Socket socket = serverSocket.accept(); 
     OutputStream oStream = socket.getOutputStream(); 
     ObjectOutputStream ooStream = new ObjectOutputStream(oStream); 

     String testString = "This is a test String"; 
     Calendar testCalendar = Calendar.getInstance(); 

     ooStream.writeObject(testCalendar); 
     ooStream.reset(); 
     ooStream.close(); 

     } catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

Android客戶端: (我創建了一個空白的項目,並添加Internet權限到清單)

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     Thread t = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Socket socket = new Socket("10.0.2.2", 49100); 
        InputStream iStream = socket.getInputStream(); 
        ObjectInputStream oiStream = new ObjectInputStream(iStream); 

        Object object = oiStream.readObject(); 
        Log.d("Test", object.toString()); 
        oiStream.close(); 

       } catch (UnknownHostException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } catch (ClassNotFoundException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     t.start(); 
    } 

} 

使用該代碼示例,如果啓動Java Server,然後在Android模擬器中運行Android Client,則應該收到錯誤消息。

我注意到android-17/android.jar中的java.util.Calendar對象與jre6中的java.util.Calendar對象不同。但是它們都共享相同的serialVersionUID 1807547505821590642L。 (這告訴我他們打算通過序列化來兼容)。

所以我想我正在尋找這裏發生了什麼的解釋,我想知道,我可以在Java和Android上使用其中一個日曆對象嗎? (如果是這樣,如何?)我應該使用不同的對象嗎?

+0

我有同樣的問題。你找到解決方案嗎? – matheuslf 2013-06-26 22:38:05

+0

我結束了使用JSON而不是對象序列化。我使用gson(http://code.google.com/p/google-gson/)來幫助抽象它,就像使用對象序列化一樣簡單透明。 – FuryComputers 2013-07-04 19:34:09

回答

3

I am attempting to use an object serialization socket connection between a Java server and an Android client

這不太可能奏效。

I realize that it is not deserializing properly.

這是一個很好的例子,說明爲什麼它不太可能正常工作。 Android致力於維護二進制API兼容性。任何類的內部實現都可能被修改,這意味着Java風格的對象序列化可能會被修改。

can I use one of the calendar objects on both Java and Android?

當然。只是不要在不同平臺之間使用Java風格的對象序列化。

要麼將​​值作爲longgetTimeInMillis())或者編寫自己的JSON/XML/protobuf /任何序列化程序。

2

JavaSE版本和Android版本之間沒有一對一的映射關係。 Android和Java的發展有所不同。看到這些SO問題:

正因爲如此,我認爲,在Android上工作的人甚至沒有費心去改變普通類的serialVersionUID。在將類從一個JDK版本發展到另一個JDK版本時,序列化兼容性是最明智的問題之一,想象一下爲保持JavaSE和Android之間的序列化兼容性而頭疼。