Data serialisasi rusak di PC tetapi tidak di perangkat Android

Saya sedang mengembangkan aplikasi lintas platform yang berjalan di PC dan Android. Aplikasi ini membuat serial objek dan menyimpannya ke file di server kami. Masalah yang saya alami adalah ketika saya melakukan deserialisasi salah satu objek di PC, saya mendapatkan kesalahan berikut:

java.io.StreamCorruptedException: invalid type code: 71
at java.io.ObjectInputStream.readString(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1736)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1706)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1344)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)

namun, saya berhasil melakukan deserialisasi objek di ponsel Android (Samsung s5). Ini benar-benar membuatku bingung. Saya telah mempersempitnya menjadi masalah platform karena saya telah mengambil string yang disandikan secara langsung dan mendekodekannya di kedua perangkat, di mana kesalahan muncul di PC dan bukan di perangkat Android. Ini menunjukkan kepada saya bahwa string yang disandikan sebenarnya tidak rusak. Apakah saya melewatkan sesuatu? Setiap saran akan dihargai.

Berikut adalah kode yang saya gunakan untuk membuat serialisasi objek:

public static String objectToString(Serializable object) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
        ObjectOutputStream obj = new ObjectOutputStream(out);
        obj.writeObject(object);
        byte[] data = out.toByteArray();
        obj.close();
        out.close();

        return new String(Base64Coder.encode(data));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public static Object stringToObject(String encodedObject) {
    try {
        ByteArrayInputStream bin = new ByteArrayInputStream(Base64Coder.decode(encodedObject));
        ObjectInputStream input = new ObjectInputStream(bin);
        try{
        return input.readObject();
        }finally{
            Gdx.app.log(TAG, "Input closed!");
            input.close();
            bin.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Juga, ini pembuat enkode Base64 I menggunakan.


person eBehbahani    schedule 28.04.2014    source sumber
comment
Dalvik masih mungkin tidak kompatibel dengan PC JRE. Dari pertanyaan itu, mengapa tidak menggunakan JSON (atau XML)?   -  person Elliott Frisch    schedule 28.04.2014
comment
Hmm, saya telah menggunakan pengkodean base64 selama beberapa waktu dan tidak mengalami masalah apa pun. Saya dapat mencoba mengubah metode serialisasi tetapi ingin menghindarinya jika memungkinkan.   -  person eBehbahani    schedule 28.04.2014


Jawaban (2)


Anda lupa mengonversi String menjadi byte[] untuk membalikkan konversi implisit byte[] ke String yang terjadi saat menjalankan new String(Base64Coder.encode(data)).

Coba ini sebagai gantinya:

public static Object stringToObject(String encodedObject) {
    try {
        byte[] byteArray = encodedObject.getBytes();
        ByteArrayInputStream bin = new ByteArrayInputStream(Base64Coder.decode(byteArray));

alih-alih:

public static Object stringToObject(String encodedObject) {
    try {
        ByteArrayInputStream bin = new ByteArrayInputStream(Base64Coder.decode(encodedObject));
person Emanuel Moecklin    schedule 28.04.2014
comment
Metode decode mengubah string menjadi array char (lihat di sini: source- code.biz/base64coder/java/Base64Coder.java.txt). Apakah itu cukup? - person eBehbahani; 28.04.2014
comment
Kamu benar. Saya berasumsi Base64Coder.encode akan mengembalikan byte[] tetapi mengembalikan char[] jadi yang saya sarankan jelas tidak diperlukan. Saya akan memeriksa apakah Base64Coder.decode(encodedObject) identik di Android dan PC. Jika identik maka Elliott Frisch mungkin benar. Jika tidak identik maka lib Base64 memiliki beberapa kekurangan dan saya akan mencoba beralih ke mis. yang Apache (commons.apache.org/proper/commons-codec). - person Emanuel Moecklin; 28.04.2014
comment
Kemungkinan lain adalah encodedObject tidak identik yang berarti memuat objek dari server sudah salah. Jika baik encodedObject maupun String base 64 yang didekode tidak berbeda dan Anda benar-benar ingin tetap menggunakan serialisasi Java, maka Anda dapat membuat serialisasi/deserialisasi objek secara manual (menggunakan metode readObject/writeObject). - person Emanuel Moecklin; 28.04.2014
comment
Objek yang dikodekan berbeda pada PC dan Android, meskipun objeknya identik. - person eBehbahani; 28.04.2014
comment
objek yang disandikan = encodedObject (parameter dalam stringToObject)? - person Emanuel Moecklin; 28.04.2014
comment
Ya, parameter encodedObject berbeda pada keduanya. - person eBehbahani; 29.04.2014
comment
Itu berarti pengunduhan objek serial sudah mengalami masalah dan Anda harus memeriksanya terlebih dahulu. - person Emanuel Moecklin; 29.04.2014

Masalahnya adalah Android hingga versi 7.0 (API 24) menggunakan implementasi Apache Harmony Java, yang format serialisasi objeknya tidak kompatibel dengan JRE "biasa".

Karena Android 7.0 menggunakan OpenJDK dan kompatibel.

Lihat juga:

person Ilya Shinkarenko    schedule 16.06.2017