When and how to implement Parcelable vs Serializable?

Asked

Viewed 10,807 times

29

After a long time using the Serializable implementation in my classes on the Java platform (Android), I discovered Parcelable, but I was in doubt regarding the following questions below:

1. When to use (choose between) Parcelable vs Serializable?
2. How to implement Parcelable and Serializable?
3. What are the performance differences between the two implementations?

1 answer

43


Come on:

1. When to use (choose between) Parcelable vs Serializable?

Using Serializable is easier and faster to implement. However, performance is worse. Using Parcelable takes a little more time to implement and is a little more complex than Serializable. Despite this, using Parcelable has a better performance.

2. How to implement Parcelable and Serializable?

Below is an example of a class that implements Parcelable.

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

public class Cliente implements Parcelable {
 private int codigo;
 private String nome;

 public Cliente(int codigo, String nome) {
   this.codigo = codigo;
   this.nome = nome;
 }

 private Cliente(Parcel p){
   codigo = from.readInt();
   nome = from.readString();
 }

 public static final Parcelable.Creator<Cliente>
   CREATOR = new Parcelable.Creator<Cliente>() {

   public Cliente createFromParcel(Parcel in) {
     return new Cliente(in);
   }

   public Cliente[] newArray(int size) {
     return new Cliente[size];
   }
 };

 public int getCodigo() {
   return codigo;
 }

 public void setCodigo(int codigo) {
   this.codigo = codigo;
 }

 public String getNome() {
   return nome;
 }

 public void setNome(String nome) {
   this.nome = nome;
 }

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

 @Override
 public void writeToParcel(Parcel dest, int flags) {
   dest.writeInt(codigo);
   dest.writeString(nome); 
 }
}

In the example, it was necessary to rewrite two methods: describeContents and writeToParcel. The first is an integer that identifies the class. The second is responsible for serializing the class information. Another important thing is the CREATOR static attribute. All classes that implement Parcelable must have this attribute, since it is the one that brings together the functionalities of a Datainputstream and Dataoutputstream to serialize and deserialize objects. Also note that it calls the private constructor Client who receives a Parcel that allows us to read data from it and pass to the attributes.

Passing the data via Intent:

Cliente cliente = new Cliente(1, "Glauber");
Intent it = new Intent(this, Teste2Activity.class);
it.putExtra("cliente", cliente);
startActivity(it);

To read the data, it’s very simple:

Cliente c =  getIntent().getExtras().getParcelable("cliente");

Now we will use Serializable:

Let’s use an example similar to what we used in Parcelable:

import java.io.Serializable;
public class Pessoa implements Serializable{

    private int codigo;
    private String nome;
    public static final long  serialVersionUID = 100L;

    public int getCodigo() {
        return codigo;
    }
    public void setCodigo(int codigo) {
        this.codigo = codigo;
    }
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
}

In doing so, you can pass objects from the Person class to other activities and even add them to lists. Behold:

ArrayList<Pessoa> pessoas = new ArrayList<Pessoa>();
pessoas.add(new Pessoa(1, "Glauber"));
pessoas.add(new Pessoa(2, "Nelson"));

Intent it = new Intent(this, Tela2Activity.class);
// Caso queira passar a lista toda use
it.putExtra("pessoas", pessoas); 
// Caso queira passar apenas um objeto
it.putExtra("pessoa", pessoas.get(0)); 
startActivity(it);

And now, let’s take back what we’ve been through:

Pessoa pessoa = (Pessoa) getIntent().getSerializableExtra("pessoa");

ArrayList<Pessoa> pessoas = (ArrayList<Pessoa>) getIntent().getSerializableExtra("pessoas");

System.out.println("Pessoa: "+ pessoa.getNome());
System.out.println("Pessoas: "+ pessoas.get(0).getNome());

3. What are the differences in the performance of the two implementations?

Parcelable is more efficient than Serializable at runtime. Below are the results of the tests done:

Methodology used in testing:

  • Imitate the process of passing object to an activity by placing an object in a package and calling Bundle # writeToParcel (Parcel, int) and then fetching it back;
  • Run this in a loop 1000 times;
  • The tested objects are the SerializableDeveloper and the ParcelableDeveloper (see test reference link)
  • Devices tested as follows: LG Nexus 4 / Android 4.2.2; Samsung Nexus 10 / Android 4.2.2; HTC Desire Z / 2.3.3.

Results: Resultados do teste.

Nexus 10 Serializable: 1.0004ms - Parcelable: 0.0850ms -- Parcelable 10.16x better.

Nexus 4 Serializable: 1.8539ms - Parcelable: 0.1824ms -- Parcelable 11.80x better.

Desire Z Serializable: 5.1224ms - Parcelable: 0.2938ms -- Parcelable 17.36x better.

Completion:

  • Parcelable is the fastest
  • Parcelable takes longer to implement
  • Serializable is easier to implement

References:

Implementation of Parcelable and Serializable

Efficiency Test

Official Documentation - Parcelable

Official Documentation - Serializable

Interesting post on Stackoverflow - (en)

What is the purpose of the Serializable interface?

  • 1

    +1 in your reply, very good^^

  • 3

    Another advantage of Serializable is that it can be used for file data persistence, unlike Parcelable. But with the exception that from one version of Java to another the serialization mechanism can change, and then your serialized objects will be lost. Useful however as temporary cache.

  • The numbers scare, but unless you’re going to pass a huge amount of elements in a Bundle, you won’t notice a difference between the two. Using Parcelable at all is premature optimization.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.