¿Cómo puedo hacer que mis objetos personalizados Parcelable?


Estoy tratando de hacer mis objetos parcelables. Sin embargo, tengo objetos personalizados y esos objetos tienen ArrayList atributos de otros objetos personalizados que he creado.

¿Cuál sería la mejor manera de hacer esto?

Author: ojonugwa ochalifu, 2011-08-25

9 answers

Puedes encontrar algunos ejemplos de esto aquí, aquí (el código se toma aquí), y aquí.

Puede crear una clase POJO para esto, pero necesita agregar un código adicional para que sea parcelable. Echa un vistazo a la implementación.

public class Student implements Parcelable{
        private String id;
        private String name;
        private String grade;

        // Constructor
        public Student(String id, String name, String grade){
            this.id = id;
            this.name = name;
            this.grade = grade;
       }
       // Getter and setter methods
       .........
       .........

       // Parcelling part
       public Student(Parcel in){
           String[] data = new String[3];

           in.readStringArray(data);
           // the order needs to be the same as in writeToParcel() method
           this.id = data[0];
           this.name = data[1];
           this.grade = data[2];
       }

       @Оverride
       public int describeContents(){
           return 0;
       }

       @Override
       public void writeToParcel(Parcel dest, int flags) {
           dest.writeStringArray(new String[] {this.id,
                                               this.name,
                                               this.grade});
       }
       public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
           public Student createFromParcel(Parcel in) {
               return new Student(in); 
           }

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

Una vez que haya creado esta clase, puede pasar fácilmente objetos de esta clase a través de la Intent como esta, y recuperar este objeto en la actividad de destino.

intent.putExtra("student", new Student("1","Mike","6"));

Aquí, el estudiante es la clave que usted require para desparcelar los datos del bundle.

Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");

Este ejemplo muestra solo tipos de cadenas. Pero, puede agrupar cualquier tipo de datos que desee. Pruébalo.

EDITAR: Otro ejemplo, sugerido por Rukmal Dias.

 410
Author: fiction,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-13 16:16:42

Aquí hay un sitio web para crear una Clase Parcelable a partir de su clase creada:

Http://www.parcelabler.com/

 185
Author: francisco_ssb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-05 13:27:48

IntelliJ IDEA y Android Studio tienen plugins para esto:

Estos plugins generan Android Parcelable código repetitivo basado en campos de la clase.

Demostración del plugin

 102
Author: naXa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-09 10:32:05

1. Importación Android Parcelable code generator

introduzca la descripción de la imagen aquí

2. Crear una clase

public class Sample {
    int id;
    String name;
}

3. Generar > Parcelable desde el menú

introduzca la descripción de la imagen aquí introduzca la descripción de la imagen aquí

Hecho.

 49
Author: phi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-24 08:07:23

¿Cómo? Con anotaciones.

Simplemente anota un POJO con una anotación especial y la biblioteca hace el resto.

¡Atención!

No estoy seguro de que Hrisey, Lombok y otras bibliotecas de generación de código sean compatibles con el nuevo sistema de compilación de Android. Pueden o no jugar bien con código de intercambio en caliente (es decir, JRebel, Instant Run).

Ventajas:

  • Las bibliotecas de generación de código te salvan de la fuente repetitiva codificar.
  • Las anotaciones hacen que tu clase sea hermosa.

Contras:

  • Funciona bien para clases simples. Hacer una clase compleja parcelable puede ser complicado.
  • Lombok y AspectJ no juegan bien juntos. [detalles]
  • Ver mis advertencias.

Hrisey

¡Atención!

Hrisey tiene un problema conocido con Java 8 y por lo tanto no se puede utilizar para el desarrollo de Android en la actualidad. Ver #1 No puede encontrar errores de símbolos (JDK 8).

Hrisey se basa en Lombok . Clase parcelable usando Hrisey :

@hrisey.Parcelable
public final class POJOClass implements android.os.Parcelable {
    /* Fields, accessors, default constructor */
}

Ahora no necesita implementar ningún método de interfaz Parcelable. Hrisey generará todo el código requerido durante la fase de preprocesamiento.

Hrisey en las dependencias de Gradle:

provided "pl.mg6.hrisey:hrisey:${hrisey.version}"

Vea aquí para los tipos soportados. El ArrayList está entre ellos.

Instalar un plugin-Hrisey xor Lombok* - para su IDE y empezar a utilizar sus características sorprendentes!

introduzca la descripción de la imagen aquí
* No habilite los complementos Hrisey y Lombok juntos o obtendrá un error durante el lanzamiento del IDE.


Parceler

Clase parcelable usando Parceler :

@java.org.parceler.Parcel
public class POJOClass {
    /* Fields, accessors, default constructor */
}

Para usar el código generado, puede hacer referencia a la clase generada directamente, o a través de la clase de utilidad Parcels utilizando

public static <T> Parcelable wrap(T input);

Para desreferenciar el @Parcel, simplemente llame al siguiente método de Parcels clase

public static <T> T unwrap(Parcelable input);

Parceler en dependencias de Gradle:

compile "org.parceler:parceler-api:${parceler.version}"
provided "org.parceler:parceler:${parceler.version}"

Busque en READMElos tipos de atributos soportados.


AutoParcel

AutoParcel es una extensión AutoValue que permite la generación de valores parcelables.

Simplemente agregue implements Parcelable a sus @AutoValue modelos anotados:

@AutoValue
abstract class POJOClass implements Parcelable {
    /* Note that the class is abstract */
    /* Abstract fields, abstract accessors */

    static POJOClass create(/*abstract fields*/) {
        return new AutoValue_POJOClass(/*abstract fields*/);
    }
}

AutoParcel en el archivo de compilación de Gradle:

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

repositories {
    /*...*/
    maven {url "https://clojars.org/repo/"}
}

dependencies {
    apt "frankiesardo:auto-parcel:${autoparcel.version}"
}

PaperParcel

PaperParcel es un procesador de anotación que genera automáticamente código repetitivo parcelable seguro para Kotlin y Java. PaperParcel admite Clases de datos Kotlin, AutoValue de Google a través de una extensión AutoValue o simplemente objetos Java bean normales.

Ejemplo de Uso de docs.
Anote su clase de datos con @PaperParcel, implemente PaperParcelable y agregue una instancia estática JVM de PaperParcelable.Creator por ejemplo:

@PaperParcel
public final class Example extends PaperParcelable {
    public static final PaperParcelable.Creator<Example> CREATOR = new PaperParcelable.Creator<>(Example.class);

    private final int test;

    public Example(int test) {
        this.test = test;
    }

    public int getTest() {
        return test;
    }
}

Para los usuarios de Kotlin, ver Kotlin Usage ; Para los usuarios de AutoValue, ver AutoValue Usage.


ParcelableGenerator

Generador de bloques (README está escrito en chino y no lo entiendo. Contribuciones a esta respuesta de desarrolladores de habla inglés-chino son bienvenidas)

Ejemplo de uso de README.

import com.baoyz.pg.Parcelable;

@Parcelable
public class User {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

El complemento android-apt ayuda a trabajar con procesadores de anotación en combinación con Android Studio.

 19
Author: naXa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 17:17:02

He encontrado la forma más sencilla de crear Clase parcelable

introduzca la descripción de la imagen aquí

 7
Author: Rjz Satvara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-10 04:38:53

Es muy fácil, se puede utilizar un plugin en android studio para hacer objetos Parcelables.

public class Persona implements Parcelable {
String nombre;
int edad;
Date fechaNacimiento;

public Persona(String nombre, int edad, Date fechaNacimiento) {
    this.nombre = nombre;
    this.edad = edad;
    this.fechaNacimiento = fechaNacimiento;
}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.nombre);
    dest.writeInt(this.edad);
    dest.writeLong(fechaNacimiento != null ? fechaNacimiento.getTime() : -1);
}

protected Persona(Parcel in) {
    this.nombre = in.readString();
    this.edad = in.readInt();
    long tmpFechaNacimiento = in.readLong();
    this.fechaNacimiento = tmpFechaNacimiento == -1 ? null : new Date(tmpFechaNacimiento);
}

public static final Parcelable.Creator<Persona> CREATOR = new Parcelable.Creator<Persona>() {
    public Persona createFromParcel(Parcel source) {
        return new Persona(source);
    }

    public Persona[] newArray(int size) {
        return new Persona[size];
    }
};}
 2
Author: App-SoftwareFactory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-01 12:29:19

Ahora puedes usar la biblioteca Parceler para convertir cualquier clase personalizada en parcelable. Simplemente anote su clase POJO con @Parcel. por ejemplo,

    @Parcel
    public class Example {
    String name;
    int id;

    public Example() {}

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getName() { return name; }

    public int getId() { return id; }
}

Puede crear un objeto de clase de ejemplo y envolver a través de Paquetes y enviar como un paquete a través de intent. por ejemplo,

Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));

Ahora para obtener un objeto de Clase personalizado solo use

Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
 0
Author: Shubham Shukla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-31 07:52:54

Para poner: bundle.putSerializable("key",(Serializable) object);

Para obtener: List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));

 -3
Author: Macário,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-14 15:10:01