349

Why does Android provide 2 interfaces for serializing objects? Do Serializable objects interopt with Android Binder and AIDL files?

live2dream95
  • 5,079
  • 8
  • 24
  • 24

15 Answers15

494

In Android we cannot just pass objects to activities. To do this the objects must either implement Serializable or Parcelable interface.

Serializable

Serializable is a standard Java interface. You can just implement Serializable interface and add override methods. The problem with this approach is that reflection is used and it is a slow process. This method creates a lot of temporary objects and causes quite a bit of garbage collection. However, Serializable interface is easier to implement.

Look at the example below (Serializable):

// MyObjects Serializable class

import java.io.Serializable;
import java.util.ArrayList;
import java.util.TreeMap;

import android.os.Parcel;
import android.os.Parcelable;

public class MyObjects implements Serializable {

    private String name;
    private int age;
    public ArrayList<String> address;

    public MyObjects(String name, int age, ArrayList<String> address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public ArrayList<String> getAddress() {
        if (!(address == null))
            return address;
        else
            return new ArrayList<String>();
    }

    public String getName() {
        return name;
    }

    public String getAge() {
        return age;
    }
}
// MyObjects instance
MyObjects mObjects = new MyObjects("name", "age", "Address array here");

// Passing MyObjects instance via intent
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects)    mIntent.getSerializableExtra("UniqueKey");

Parcelable

Parcelable process is much faster than Serializable. One of the reasons for this is that we are being explicit about the serialization process instead of using reflection to infer it. It also stands to reason that the code has been heavily optimized for this purpose.

Look at the example below (Parcelable):

// MyObjects Parcelable class

import java.util.ArrayList;

import android.os.Parcel;
import android.os.Parcelable;

public class MyObjects implements Parcelable {

    private int age;
    private String name;
    private ArrayList<String> address;

    public MyObjects(String name, int age, ArrayList<String> address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public MyObjects(Parcel source) {
        age = source.readInt();
        name = source.readString();
        address = source.createStringArrayList();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(age);
        dest.writeString(name);
        dest.writeStringList(address);
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public ArrayList<String> getAddress() {
        if (!(address == null))
            return address;
        else
            return new ArrayList<String>();
    }

    public static final Creator<MyObjects> CREATOR = new Creator<MyObjects>() {
        @Override
        public MyObjects[] newArray(int size) {
            return new MyObjects[size];
        }

        @Override
        public MyObjects createFromParcel(Parcel source) {
            return new MyObjects(source);
        }
    };
}
// MyObjects instance
MyObjects mObjects = new MyObjects("name", "age", "Address array here");

// Passing MyOjects instance
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects) mIntent.getParcelableExtra("UniqueKey");

You can pass ArrayList of Parcelable objects as below:

// Array of MyObjects
ArrayList<MyObjects> mUsers;

// Passing MyOjects instance
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putParcelableArrayListExtra("UniqueKey", mUsers);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
ArrayList<MyObjects> mUsers = mIntent.getParcelableArrayList("UniqueKey");

Conclusion

  1. Parcelable is faster than Serializable interface
  2. Parcelable interface takes more time to implement compared to Serializable interface
  3. Serializable interface is easier to implement
  4. Serializable interface creates a lot of temporary objects and causes quite a bit of garbage collection
  5. Parcelable array can be passed via Intent in android
Mahozad
  • 6,430
  • 9
  • 43
  • 70
Sujith
  • 6,655
  • 1
  • 23
  • 36
  • 2
    @Sujith what do you mean by *reflection is used*? What is **reflection**? – AnV Oct 01 '16 at 14:31
  • 11
    @AbhinavVutukuri Reflection is the term for inspecting objects, fields and methods at run-time via Object.getClass() and such. – FaultException Oct 02 '16 at 10:18
  • what about boolean variables? how to read boolean values from parcel? source.readBoolean() not found... – Himanshu Mori Jan 05 '17 at 10:20
  • 1
    got it... http://stackoverflow.com/questions/6201311/how-to-read-write-a-boolean-when-implementing-the-parcelable-interface – Himanshu Mori Jan 05 '17 at 10:20
  • Does serialization copy the object, or send the reference? Let's say I have a Dog dog = new Dog(); in my MainActivity. Can I access this object in the new activity? Or is the object only copied, and I can only access a new object? – Einar Jan 15 '17 at 03:04
  • 3
    Serializables are better for persisting data , parcelable objects on the other hand should not be persisted at all . It's a really bad practice – TheAnimatrix Mar 25 '17 at 11:16
  • 4
    @Sujith As more than one person has stated, Parcelable objects can't be persisted (reliably) but Serializable ones can (within limits). Since your answer is the highest-scoring and gives the impression of covering all the important differences, you should probably mention that point. – LarsH Jul 27 '17 at 13:33
  • 7
    Now the implementation of Parcelable is as fast as Serializable, just press ALT + INSERT on any class implementing Parcelable in Android Studio and the IDE will do it. – Ali Nem Nov 25 '17 at 07:37
  • So for `Parcel` , if reflections is not used, then how the data is transmitted among VMs like Serialization does for JVMs ? And does parcel data read using `ParcelObject.getterMethods()` and if not found, will it throw an exception? – kAmol Apr 02 '19 at 04:50
  • @kAmol Parcelable is simply an interface for converting an object into its primitive types and vice-versa. – Zintom Jan 15 '21 at 19:35
199

Serializable is a standard Java interface. You simply mark a class Serializable by implementing the interface, and Java will automatically serialize it in certain situations.

Parcelable is an Android specific interface where you implement the serialization yourself. It was created to be far more efficient that Serializable, and to get around some problems with the default Java serialization scheme.

I believe that Binder and AIDL work with Parcelable objects.

However, you can use Serializable objects in Intents.

SMR
  • 6,320
  • 2
  • 32
  • 55
Cheryl Simon
  • 44,959
  • 14
  • 91
  • 82
  • 1
    how do I serialize a Parcelable object? How do I make it persistent? – Hades Jul 12 '11 at 11:43
  • @Haded Get the contents of the objects state and store it in a file or SQLLite database. Seriliasing is useful for making objects transferable between different components in android or different applications altogether. – Jonathan Apr 04 '13 at 23:38
  • 7
    This is a great explanation. I also noticed this: "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." http://developer.android.com/reference/android/os/Parcel.html – Sam003 Mar 11 '15 at 19:12
  • @Zhisheng what is meant by arbitrary objects? what kind of objects we can put into the Parcel? – hasnain_ahmad Nov 16 '15 at 12:39
  • How about converting objects to json string instead with gson? – F.O.O Sep 10 '16 at 08:51
79

Parcelable vs Serializable I refer these two.

For Java and Kotlin

1) Java

Serializable, the Simplicity

What is Serializable?

Serializable is a standard Java interface. It is not a part of the Android SDK. Its simplicity is its beauty. Just by implementing this interface your POJO will be ready to jump from one Activity to another.

public class TestModel implements Serializable {

String name;

public TestModel(String name) {
    this.name = name;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}
  • 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. This mechanism also tends to create a lot of temporary objects and cause quite a bit of garbage collection.

Parcelable, The Speed

What is Parcelable?

Parcelable is another interface. Despite its 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.

public class TestModel implements Parcelable {


String name;

public TestModel(String name, String id) {
    this.name = name;
}

protected TestModel(Parcel in) {
    this.name = in.readString();


}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.name);

}

public static final Parcelable.Creator<TestModel> CREATOR = new Parcelable.Creator<TestModel>() {
    @Override
    public TestModel createFromParcel(Parcel source) {
        return new TestModel(source);
    }

    @Override
    public TestModel[] newArray(int size) {
        return new TestModel[size];
    }
};
}

Now, The winner is

enter image description here

The results of the tests conducted by Philippe Breault show that Parcelable is more than 10x faster than Serializable. Some other Google engineers stand behind this statement as well.

According to them, the default Serializable approach is slower than Parcelable. And here we have an agreement between the two parties! BUT, it is unfair to compare these two at all! Because with Parcelable we are actually writing custom code. Code specifically created for that one POJO. Thus, no garbage is created and the results are better. But with the default Serializable approach, we rely on the automatic serialization process of Java. The process is apparently not custom at all and creates lots of garbage! Thus, the worse results.

Stop Stop!!!!, Before making decision

Now, there is another approach. The whole automatic process behind Serializable can be replaced by custom code which uses writeObject() & readObject() methods. These methods are specific. If we want to rely on the Serializable approach in combination with custom serialization behavior, then we must include these two methods with the same exact signature as the one below:

 private void writeObject(java.io.ObjectOutputStream out)
 throws IOException;

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

 private void readObjectNoData()
     throws ObjectStreamException;

And now a comparison between Parcelable and custom Serializable seems fair! The results may be surprising! The custom Serializable approach is more than 3x faster for writes and 1.6x faster for reads than Parcelable.

Edited:-----

2) Kotlinx Serialization

Kotlinx Serialization Library

For Kotlin serialization need to add below dependency and plugin

implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1"

apply plugin: 'kotlinx-serialization'

Your build.gradle file

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlinx-serialization'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.smile.kotlinxretrosample"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.okhttp3:okhttp:3.12.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

Serializing is done quite easily, you need to annotate the intended class with the @Serializable annotation as below

import kotlinx.serialization.Serializable
@Serializable
class Field {
    var count: Int = 0
    var name: String = ""
}

Two more annotations to note are transient and optional. Using transient will have the serializer ignore that field and using optional will allow the serializer not to break if a field is missing, but at the same time a default value will need to be provided.

@Optional
var isOptional: Boolean = false
@Transient
var isTransient: Boolean = false

Note: This can as well work with data classes.

Now to actually use this in action let’s take an example of how to convert a JSON to object and back

 fun toObject(stringValue: String): Field {
        return JSON.parse(Field.serializer(), stringValue)
    }

    fun toJson(field: Field): String {
        //Notice we call a serializer method which is autogenerated from our class 
        //once we have added the annotation to it
        return JSON.stringify(Field.serializer(), field)
    }

For more

Farhana Naaz Ansari
  • 8,382
  • 15
  • 63
  • 97
40

If you want to be a good citizen, take the extra time to implement Parcelable since it will perform 10 times faster and use less resources.

However, in most cases, the slowness of Serializable won’t be noticeable. Feel free to use it but remember that serialization is an expensive operation so keep it to a minimum.

If you are trying to pass a list with thousands of serialized objects, it is possible that the whole process will take more than a second. It can make transitions or rotation from portrait to lanscape feel very sluggish.

Source to this point: http://www.developerphil.com/parcelable-vs-serializable/

hichris123
  • 9,735
  • 15
  • 51
  • 66
codercat
  • 21,439
  • 9
  • 56
  • 84
35

In Parcelable, developers write custom code for marshalling and unmarshalling so it creates fewer garbage objects in comparison to Serialization. The performance of Parcelable over Serialization dramatically improves (around two times faster), because of this custom implementation.

Serializable is a marker interface, which implies that user cannot marshal the data according to their requirements. In Serialization, a marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java object's member and behavior, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in comparison to Parcelable.

Edit: What is the meaning of marshalling and unmarshalling?

In few words, "marshalling" refers to the process of converting the data or the objects into a byte-stream, and "unmarshalling" is the reverse process of converting the byte-stream back to their original data or object. The conversion is achieved through "serialization".

http://www.jguru.com/faq/view.jsp?EID=560072

Uts
  • 4,200
  • 2
  • 18
  • 31
23

Parcelable is sort of a standard in Android development. But not because of speed

Parcelable is recommended approach for data transfers. But if you use serializable correctly as shown in this repo, you will see that serializable is sometimes even faster then parcelable. Or at least timings are comparable.

Is Parcelable faster then Serializable?

No, if serialization is done right.

Usual Java serialization on an average Android device (if done right *) is about 3.6 times faster than Parcelable for writes and about 1.6 times faster for reads. Also it proves that Java Serialization (if done right) is fast storage mechanism that gives acceptable results even with relatively large object graphs of 11000 objects with 10 fields each.

* The sidenote is that usually everybody who blindly states that "Parcelable is mush faster" compares it to default automatic serialization, which uses much reflection inside. This is unfair comparison, because Parcelable uses manual (and very complicated) procedure of writing data to the stream. What is usually not mentioned is that standard Java Serializable according to the docs can also be done in a manual way, using writeObject() and readObject() methods. For more info see JavaDocs. This is how it should be done for the best performance.

So, if serializable is faster and easier to implement, why android has parcelable at all?

The reason is native code. Parcelable is created not just for interprocess communication. It also can be used for intercode communication. You can send and recieve objects from C++ native layer. That's it.

What should you choose? Both will work good. But I think that Parcelable is better choice since it is recommended by google and as you can see from this thread is much more appreciated.

Maksim Turaev
  • 3,359
  • 24
  • 37
  • Can you site your sources? I would really appreciate it. Thanks!! – Archie G. Quiñones Feb 09 '19 at 16:11
  • 2
    That answer I got from experienced developer who work on AOSP related project https://twitter.com/bwdude. He said that native C++ code for communication with SDK layer uses its own implementation of Parcelable. I guess he talk about this class https://android.googlesource.com/platform/frameworks/native/+/brillo-m10-dev/include/binder/Parcelable.h I know that this is not the best explanation, but it is the best I have right now. If you will find something else, be sure to post it here =) – Maksim Turaev Feb 09 '19 at 19:11
  • Wish I could upvote you more than once. I have seen great Android and Java experts go for the most upvoted answer here. Lack of documentation has really prevented any limelight for Serializable. Feels like these are effects of promoting a specific API. THanks! – Manish Kumar Sharma Jul 21 '19 at 13:24
  • Can you explain what is inter-code communication – linjiejun Dec 29 '20 at 07:55
  • I guess that's when you want to communicate between c++ and java. Not only between java and java. – Maksim Turaev Dec 29 '20 at 08:51
20

I'm actually going to be the one guy advocating for the Serializable. The speed difference is not so drastic any more since the devices are far better than several years ago and also there are other, more subtle differences. See my blog post on the issue for more info.

Nemanja Kovacevic
  • 3,362
  • 2
  • 28
  • 45
  • 1
    Thank you for the share. Its less complex to implement serializeable and the trade off needs to be decided in those rare and hyper optimization cases. – Ankan-Zerob Jul 01 '15 at 17:32
  • 2
    The alternative viewpoint, especially when backed with experiments and results, is very helpful. I have to work with a lot of existing Parcelable based source code, and may refactor some of it now that I've read your blog post. – Les Mar 23 '17 at 11:49
11

1. Serializable

@see http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

Interface of what?

  • is a standard Java interface

Speed

  • slower than Parcelable

2. Parcelable

@see http://developer.android.com/reference/android/os/Parcelable.html

Interface of what?

  • is android.os interface
    • which means Google developped Parcelable for better performance on android

Speed

  • faster ( because it is optimized for usage on android development)

> In Conclusion

Be aware that Serializable is a standard Java interface, and Parcelable is for Android Development

kenju
  • 5,248
  • 1
  • 36
  • 40
7

There is some performance issue regarding to marshaling and unmarshaling. Parcelable is twice faster than Serializable.

Please go through the following link:

http://www.3pillarglobal.com/insights/parcelable-vs-java-serialization-in-android-app-development

twlkyao
  • 13,208
  • 7
  • 24
  • 39
Tushar Thakar
  • 304
  • 2
  • 7
4

Implementation of parcelable can be faster if you use paracelable plugin in android studio. search for Android Parcelable code generator

Deep P
  • 498
  • 5
  • 12
4

The Serializable interface can be used the same way as the Parcelable one, resulting in (not much) better performances. Just overwrite those two methods to handle manual marshalling and unmarshalling process:

private void writeObject(java.io.ObjectOutputStream out)
    throws IOException
private void readObject(java.io.ObjectInputStream in)
    throws IOException, ClassNotFoundException

Still, it seems to me that when developing native Android, using the Android api is the way to go.

See :

Ceyfiroth
  • 87
  • 1
  • 11
1

you can use the serializable objects in the intents but at the time of making serialize a Parcelable object it can give a serious exception like NotSerializableException. Is it not recommended using serializable with Parcelable . So it is better to extends Parcelable with the object that you want to use with bundle and intents. As this Parcelable is android specific so it doesn't have any side effects. :)

twlkyao
  • 13,208
  • 7
  • 24
  • 39
Rankush Kumar
  • 156
  • 2
  • 13
1

Parcelable much faster than serializable with Binder, because serializable use reflection and cause many GC. Parcelable is design to optimize to pass object.

Here's link to reference. http://www.developerphil.com/parcelable-vs-serializable/

Horyun Lee
  • 993
  • 7
  • 8
1

I am late in answer, but posting with hope that it will help others.

In terms of Speed, Parcelable > Serializable. But, Custom Serializable is exception. It is almost in range of Parcelable or even more faster.

Reference : https://www.geeksforgeeks.org/customized-serialization-and-deserialization-in-java/

Example :

Custom Class to be serialized

class MySerialized implements Serializable { 

    String deviceAddress = "MyAndroid-04"; 

    transient String token = "AABCDS"; // sensitive information which I do not want to serialize

    private void writeObject(ObjectOutputStream oos) throws Exception {
        oos.defaultWriteObject();
        oos.writeObject("111111" + token); // Encrypted token to be serialized
    }

    private void readObject(ObjectInputStream ois) throws Exception {
        ois.defaultReadObject(); 
        token = ((String) ois.readObject()).subString(6);  // Decrypting token
    }

}
Kushal
  • 6,695
  • 6
  • 48
  • 72
0

Serializable

Serializable is a markable interface or we can call as an empty interface. It doesn’t have any pre-implemented methods. Serializable is going to convert an object to byte stream. So the user can pass the data between one activity to another activity. The main advantage of serializable is the creation and passing data is very easy but it is a slow process compare to parcelable.

Parcelable

Parcel able is faster than serializable. Parcel able is going to convert object to byte stream and pass the data between two activities. Writing parcel able code is little bit complex compare to serialization. It doesn’t create more temp objects while passing the data between two activities.