jueves, agosto 11, 2016

Parcelable en Español

Parcelable

Interfaz para clases cuya instancias pueden ser escritas y restauradas de un Parcel.

Parcel

Paquete, grupo o montón. Contenedor para un mensaje (data y referencias de objeto) que puede ser enviado a través de IBinder. 

Bien ¿y que hacemos con eso?

Cuando pasamos parámetros a un Intent, o un fragmento o actividad dentro de un Bundle podemos pasar todo un objeto, ¿cómo?  implementando Parcelable en nuestra clase.  Anteriormente utilizaba Serializable, pero es recomendable utilizar Parcelable  en vez de Serializable sencillamente porque es mucho más rápido. Se pueden leer este artículo de Philippe Breaul Ingeniero de Software en Google Parcelable vs Serializable para más  detalle sobre las diferencias de ambos.

Supongamos que vamos a enviar parámetros a un IntentService para un Login por ejemplo,

LoginRequest loginRequest = new LoginRequest(this,
                    mEmailView.getText().toString(),
                    mPasswordView.getText().toString());

Intent loginService = new Intent(this, LoginIntentService.class);
loginService.putExtra(LoginIntentService.PARAM_LOGIN, loginRequest);


El método putExtra acepta un Parcelable, en este caso tengo un objeto loginRequest con mi usuario y contraseña pero, para que eso se pueda hacer LoginRequest tiene que implementar Parcelable, así:


public class LoginRequest implements Parcelable {


    @SuppressWarnings("unused")
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        @Override
        public LoginRequest createFromParcel(Parcel in) {
            return new LoginRequest(in);
        }

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

    private String email;
    private String password;

    /**
     * Default private request
     */
    private LoginRequest() {
    }

    /**
     * Constructor of this class
     *
     * @param context  Android context
     * @param email    Email
     * @param password Password
     */
    public LoginRequest(Context context, String email, String password) {
        this.email = email;
        this.password = password;
        this.device = new Device(DeviceManager.getDeviceName(), DeviceManager.getDeviceID(context));
    }

    /**
     * Constructor for Parcel
     *
     * @param in in parce
     */
    private LoginRequest(Parcel in) {
        email = in.readString();
        password = in.readString();
        device = (Device) in.readValue(Device.class.getClassLoader());
    }


    /**
     * Implementation of describeContent of Parcelable interface
     *
     * @return 0
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * WriteToParce implementation
     *
     * @param dest  destination
     * @param flags flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(email);
        dest.writeString(password);
        dest.writeValue(device);
    }
}

Los métodos del Parcelable  están en negritas y todos son importantes y necesarios. Se podría pensar que es mucho código, y lo es, más aún si tenemos muchos campos en nuestra clase. Afortunadamente Android Studio nos hace todo el trabajo. Vale mencionar que uso la versión 2.2 Beta.

Lo único que tenemos que hacer es escribir nuestra clase LoginRequest implements Parcelable y los miembros de la clase, algo así:



Nos va marcar que algo está mal, en Mac presionamos alt + enter en el nombre de la clase.



Seleccionamos Add Parcelable implementation y automáticamente nos genera todos los métodos necesarios.

Quedando como resultado 


Saludos, espero empiecen a utilizar Parcelable de ahora en adelante para pasar todo un objeto y no parámetro por parámetro como he visto en algunos códigos en Internet.