Tip Android #11: usar Parcelable en lugar de Serializable

02/03/2013android tip

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:

  1. Implementar el método writeToParcel para «descomponerla» en un Parcel
  2. 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.
  3. 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

<< TIPS ANDROID

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.