Android serializable problem

serialization and deserialization in android
android serializable example
what is serializable in android
json serialization in android
android serialize bitmap
android file serializable
android serializable and parcelable difference
android serialize object to string

I created a class, which has several member variables, all of which are serializable... except one Bitmap! I tried to extend bitmap and implement serializable, not thinking Bitmap is a final class.

I want to save the class (it basically forms the current state of a game) so a player can pick-up and load the game.

The way I see it I have two options: 1) Find another way to save the game state. Any help here would be appreciated.

2) change the bitmap member variable to an int, say, and create a BitmapGetter class that has a static method returning bitmaps based on ints. (This option is not easy, as my class contains so many bitmap possiblities and the way I created the game means this will require an incredible amount of effort.

Basically I have no one to blame but myself for lazily creating a bitmap variable without thinking, but I would appreciate any help...

How about replacing Bitmap with a class like this:

public class SerialBitmap implements Serializable {

    public Bitmap bitmap;

    // TODO: Finish this constructor
    SerialBitmap(<some params>) {
        // Take your existing call to BitmapFactory and put it here
        bitmap = BitmapFactory.decodeSomething(<some params>);
    }

    // Converts the Bitmap into a byte array for serialization
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 0, byteStream);
        byte bitmapBytes[] = byteStream.toByteArray();
        out.write(bitmapBytes, 0, bitmapBytes.length);
    }

    // Deserializes a byte array representing the Bitmap and decodes it
    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        int b;
        while((b = in.read()) != -1)
            byteStream.write(b);
        byte bitmapBytes[] = byteStream.toByteArray();
        bitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
    }
}

The overridden Serializable.writeObject() and readObject() methods serialize the bytes instead of the Bitmap so the class is serializable. You will need to finish the constructor because I don't know how you currently construct your Bitmap. The last thing to do is to replace references to YourClass.bitmap with YourClass.serialBitmap.bitmap.

Good luck!

Barry P.S. This code compiles but I haven't tested it with a real bitmap

Serializable, It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime. During deserialization, the fields of  Implementing the Serializable interface on SealedClass is all we need to do in order to serialise this class hierarchy. While this appears to work it actually breaks the singleton implementation of Object and Object2 and using objects that have been serialised. The reason for this is that the Java serialiser has absolutely no knowledge of a Kotlin object or even that this is actually a Java class that has a specific singleton contract, and when it deserialises one of these classes it invokes

I had the same problem.

And i decided like this.

Bitmap is Parcelable, so I made following to my class.

  1. I made Constructor which gets Bundle object , and getter that returns Bundle representing Objects data. So while Bitmap is parcelable , Bundle can save bitmap as parcelable in it.

  2. When you need to pass Date in intent , you can call objects getBundle() method and pass with Intent.putExtra(String key,Bundle value)

  3. In target activity you will call getBundle(String key) and pass it to constructor.

    I think it's very easy approach.

Parcelable vs Serializable, Serializable is a standard Java interface. It is not a part of the Android SDK. It's simplicity is it's beauty. Just by implementing this interface your  Using Parcelable compared to Serializable can achieve up to 10x performance increase in many cases for transport which is why it's the Android preferred method. Caveats. There are a few common gotchas associated to Parcelable to consider below:

Here is a general bitmap wrapper: (Edit from Barry Fruitman answer)

    public class SerialBitmap implements Serializable {

    private Bitmap bitmap;
    private transient Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.PNG;
    private transient int compressQuality = 100;

    public SerialBitmap(Bitmap bitmap)
    {
        this.bitmap = bitmap;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void recycle() {
        if (bitmap!=null && !bitmap.isRecycled()) bitmap.recycle();
    }
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(compressFormat, compressQuality, stream);

        byte[] byteArray = stream.toByteArray();

        out.writeInt(byteArray.length);
        out.write(byteArray);

    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {


        int bufferLength = in.readInt();

        byte[] byteArray = new byte[bufferLength];

        int pos = 0;
        do {
            int read = in.read(byteArray, pos, bufferLength - pos);

            if (read != -1) {
                pos += read;
            } else {
                break;
            }

        } while (pos < bufferLength);

        bitmap = BitmapFactory.decodeByteArray(byteArray, 0, bufferLength);

    }

    public Bitmap.CompressFormat getCompressFormat() {
        return compressFormat;
    }

    public void setCompressFormat(Bitmap.CompressFormat compressFormat) {
        this.compressFormat = compressFormat;
    }

    public int getCompressQuality() {
        return compressQuality;
    }

    public void setCompressQuality(int compressQuality) {
        this.compressQuality = compressQuality;
    }
}

if you want to compress the bitmap and make the serial object smaller you can set the compression via setCompressFormat and setCompressQuality.

Example:

setCompressFormat(Bitmap.CompressFormat.JPEG);
setCompressQuality(80);

If you are using Progourd, add the following rules:

-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

Parcelable vs. Java Serialization in Android App Development, Serialization, on the other hand, is a Java interface that allows users to implement the interface which gets marked as Serializable. During the Android application  Android Platform. API level 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1. Manifest.permission. Manifest.permission_group. android.accessibilityservice. AccessibilityService.MagnificationController.OnMagnificationChangedListener. AccessibilityService.SoftKeyboardController.OnShowModeChangedListener.

First of all, you should serialize via Parcelable. It's an Android class and it usually works great, out of the box: and you can serialize a ByteArray with it, with the methods:

public final void writeByteArray (byte[] b)

and

public final void readByteArray (byte[] val)

You might want to check Parcel documentation too.

New Android Serialization Vulnerability Gives Underprivileged Apps , One Class to Rule Them All: New Android Serialization Vulnerability found, we feel that a general problem deserves a general mitigation,  Despite it’s rival (Serializable in case you forgot), it is a part of the Android SDK. Now, Parcelable was specifically designed in such a way that there is no reflection when using it. That is because, we are being really explicit for the serialization process.

You can do the serialization by hand by using the following java methods:

private void writeObject(java.io.ObjectOutputStream out)
private void readObject(java.io.ObjectInputStream in)

Serialize the bitmap by using getPixels and when you do the deserialization you can use createBitmap to recreate it from scratch.

You can read about on how to use readObject and writeObject here: http://download.oracle.com/javase/6/docs/api/java/io/Serializable.html

Non-serializable field - Java queries, be serializable otherwise it causes the class to fail to serialize with a '​NotSerializableException'. ID: java/non-serializable-field. Kind: problem. The beauty of serializable is that you only need to implement the Serializable interface on a class and its children. It is a marker interface, meaning that there is no method to implement, Java will simply do its best effort to serialize it efficiently. The problem with this approach is that reflection is used and it is a slow process.

Serialization and Deserialization in Java with Example , Which Java libraries are useful for competitive programming? How to create a COVID-19 Tracker Android App · Program to calculate Electricity Bill · Sum of all  Serialization solves the problem of persisting an object graph to a stream (memory, file system, etc). An ORM handles the mapping of pieces of information to database columns and the retrieval and instantiation of objects, in addition to providing niceties such as searching and lazy loading.

Introducing Serial: improved data serialization on Android, While other Java serialization libraries like Kryo and Flatbuffer attempt to solve some overlapping problems, no libraries that we found fit these  Parcelable is an Android-specific interface, created to be far more efficient than Serializable, and also to fix problems around regular Java serialization. It is not used exclusively on Android, though.

Script Serialization - Unity, This causes significant problems for backwards compatibility: It carries a high risk of error because it is too easy for data to get out of sync. Avoid nested, recursive  This causes significant problems for backwards compatibility: It carries a high risk of error because it is too easy for data to get out of sync. Avoid nested, recursive structures where you reference other classes.The layout of a serialized structure always needs to be the same; independent of the data and only dependent on what is exposed in the script.

Comments
  • Check out the answer to [this question][1]. It seems to be the same question. [1]:stackoverflow.com/questions/3628016/…
  • I don't recommend using Parcelable as the Parcel documentation specifically warns against using it as a general-purpose serialization mechanism.
  • I would advise against this. From the Parcel docs: "Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable."