Reputation: 6057
Why does Android provide 2 interfaces for serializing objects? Do Serializable objects interopt with Android Binder
and AIDL files?
Upvotes: 426
Views: 269220
Reputation: 7753
In Android, passing objects between activities cannot be done directly. Objects must implement either the Serializable or Parcelable interface. Below is a detailed explanation of both approaches along with examples and a comparison to help you choose the right method.
Serializable is a standard Java interface. To use it, you simply mark your class with the Serializable
interface. However, this approach uses reflection, which can make it slower and less efficient. It also generates temporary objects that increase garbage collection overhead. Despite these downsides, Serializable is easier to implement than Parcelable.
import java.io.Serializable;
import java.util.ArrayList;
public class MyObjects implements Serializable {
private static final long serialVersionUID = 1L; // Add versioning support
private String name;
private int age;
public ArrayList<String> address;
public MyObjects(String name, int age, ArrayList<String> address) {
this.name = name;
this.age = age;
this.address = address;
}
public ArrayList<String> getAddress() {
return address != null ? address : new ArrayList<>();
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
Passing an object using Serializable:
// Creating an instance of MyObjects
MyObjects mObjects = new MyObjects("John Doe", 25, new ArrayList<>());
// Passing MyObjects instance via Intent
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
Retrieving the object in the target activity:
// Getting MyObjects instance
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects) mIntent.getSerializableExtra("UniqueKey");
// For API 33+ (Android 13 and higher)
MyObjects workorder = mIntent.getSerializableExtra("UniqueKey", MyObjects.class);
Parcelable is Android's preferred serialization method. It is faster than Serializable because it avoids reflection and uses optimized code for marshalling and unmarshalling. While traditionally requiring more boilerplate code, modern Android development offers tools to simplify implementation.
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
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;
}
protected MyObjects(Parcel in) {
age = in.readInt();
name = in.readString();
address = in.createStringArrayList();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
dest.writeStringList(address);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<MyObjects> CREATOR = new Creator<MyObjects>() {
@Override
public MyObjects createFromParcel(Parcel in) {
return new MyObjects(in);
}
@Override
public MyObjects[] newArray(int size) {
return new MyObjects[size];
}
};
public int getAge() {
return age;
}
public String getName() {
return name;
}
public ArrayList<String> getAddress() {
return address != null ? address : new ArrayList<>();
}
}
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class MyObjects(
val name: String,
val age: Int,
val address: ArrayList<String>
) : Parcelable
Passing an object using Parcelable:
// Creating an instance of MyObjects
MyObjects mObjects = new MyObjects("John Doe", 25, new ArrayList<>());
// Passing MyObjects instance via Intent
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
Retrieving the object in the target activity:
// For API 32 and below
MyObjects workorder = mIntent.getParcelableExtra("UniqueKey");
// For API 33+ (Android 13 and higher)
MyObjects workorder = mIntent.getParcelableExtra("UniqueKey", MyObjects.class);
You can also pass an ArrayList
of Parcelable
objects as shown below:
// ArrayList of MyObjects
ArrayList<MyObjects> mUsers = new ArrayList<>();
mUsers.add(new MyObjects("John Doe", 25, new ArrayList<>()));
mUsers.add(new MyObjects("Jane Doe", 30, new ArrayList<>()));
// Passing the ArrayList via Intent
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putParcelableArrayListExtra("UniqueKey", mUsers);
startActivity(mIntent);
Retrieving the ArrayList in the target activity:
// For API 32 and below
ArrayList<MyObjects> mUsers = mIntent.getParcelableArrayListExtra("UniqueKey");
// For API 33+ (Android 13 and higher)
ArrayList<MyObjects> mUsers = mIntent.getParcelableArrayListExtra("UniqueKey", MyObjects.class);
Feature | Serializable | Parcelable |
---|---|---|
Speed | Slower (reflection) | Faster (optimized) |
Ease of Implementation | Easier | More complex (but simplified with @Parcelize) |
Memory Usage | Higher (temporary objects) | Lower |
Garbage Collection | More garbage created | Minimal garbage |
Use Case | Suitable for simple tasks or non-Android specific use cases | Recommended for Android apps |
Versioning Support | Built-in via serialVersionUID | Manual implementation required |
Upvotes: 596
Reputation: 5918
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 users cannot marshal the data according to their requirements. In Serialization, a marshalling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java object's member and behaviour, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in comparison to Parcelable.
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
Upvotes: 60
Reputation: 8112
Parcelable converts an object to byte stream to pass the object between processes in Android.
Serialization converts POJO to a String (JSON String) and be used across platforms to transfer object info.
Upvotes: 1
Reputation: 339
1. Serializable
The interface is a marker (an interface without abstract methods), nothing needs to be redefined.
2. Parcelable
An interface that has abstract methods. When implementing it, you need to redefine all abstract methods, specifying which fields and in what order you need to write/read (Usually the studio itself can generate them).
Practically no one writes in Kotlin. There is a special annotation for this, thanks to which the implementation of this interface will be generated automatically. To use it, you need to add a special plugin.
You don't have to worry about implementing methods, all you need is to implement the Parcelable interface and add the @Parcelize annotation.
Everything will be fine and work quickly!
Results
The implementation process is faster if you implement the Parcelable interface instead of Serializable.
Upvotes: 4
Reputation: 4325
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.
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.
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.
Upvotes: 46
Reputation: 8478
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
}
}
Upvotes: 2
Reputation: 149
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.
Upvotes: 0
Reputation: 3560
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.
Upvotes: 23
Reputation: 166
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. :)
Upvotes: 1
Reputation: 322
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
Upvotes: 8
Reputation: 87
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 :
Upvotes: 4
Reputation: 557
Implementation of parcelable can be faster if you use paracelable plugin in android studio. search for Android Parcelable code generator
Upvotes: 4
Reputation: 23271
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/
Upvotes: 43
Reputation: 5954
@see http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
@see http://developer.android.com/reference/android/os/Parcelable.html
Be aware that Serializable is a standard Java interface, and Parcelable is for Android Development
Upvotes: 12
Reputation: 46844
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.
Upvotes: 224
Reputation: 1093
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/
Upvotes: 2