02/03/2013
Para pasar datos entre dos Activities, simplemente las incluímos en el Intent con un intent.putExtra. En el caso de que usemos objetos pertenecientes a clases que hayamos creado, en principio es suficiente con que sean serializables, esto es, que implementen la interfaz Serializable , estándar de Java, y recuperar esos objetos en la Activity de destino con getIntent().getSerializableExtra.
Sin embargo, bibliografía y blogs suelen indicar que el rendimiento del mecanismo estándar de serialización de Java tiene un rendimiento realmente pobre en Android, motivo por el cual disponemos de la interfaz Parcelable cuyo uso es altamente recomendado por su rendimiento superior, especialmente para el intercambio de datos entre procesos usando Android Interface Definition Language (AIDL). Eso sí, en comparación con la serialización estándar de Java tendremos que escribir algo de código pero no es complicado.
Al hacer una clase Parcelable, hay que:
- Implementar el método writeToParcel para «descomponerla» en un Parcel
- Declarar el atributo public static Creator que implementa Parcelable.Creator, una especie de factoría que permitirá «reconstruir» el objeto original. Tendremos también como consecuencia que hacer un constructor que reciba los atributos de nuestra clase contenidos en un objeto de tipo Parcel.
- Implementar describeContents y que devuelva cero. Este método se usa para añadir información adicional al Parcelable en casos muy concretos.
Un ejemplo sencillo pero ilustrativo de un bean convetido en Parcelable gracias al código resaltado:
package com.danielme.tipsandroid; import java.util.Calendar; import android.os.Parcel; import android.os.Parcelable; public class Persona implements Parcelable { private Long id; private String nombre; private String apellidos; private Calendar fechaNacimiento; public static final Parcelable.Creator<Persona> CREATOR = new Parcelable.Creator<Persona>() { @Override public Persona createFromParcel(Parcel parcel) { return new Persona(parcel); } @Override public Persona[] newArray(int size) { return new Persona[size]; } }; public Persona(Parcel parcel) { //seguir el mismo orden que el usado en el método writeToParcel id = parcel.readLong(); nombre = parcel.readString(); apellidos = parcel.readString(); fechaNacimiento = (Calendar) parcel.readSerializable(); } public Persona() { super(); } @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeLong(id); parcel.writeString(nombre); parcel.writeString(apellidos); parcel.writeSerializable(fechaNacimiento); } @Override public int describeContents() { return 0; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public Calendar getFechaNacimiento() { return fechaNacimiento; } public void setFechaNacimiento(Calendar fechaNacimiento) { this.fechaNacimiento = fechaNacimiento; } }
En la Activity destino se recuperará el objeto con getIntent().getParcelableExtra.
Nota 1: hay una herramienta online que nos ayudará a «parcelar» nuestros beans 😉
Nota 2: Comparativa de rendimiento