Estoy tratando de hacer mis objetos Parcelable. Sin embargo, tengo objetos personalizados y esos objetos tienen ArrayList
atributos de otros objetos personalizados que he creado.
Cuál sería la mejor forma de hacer esto?
Estoy tratando de hacer mis objetos Parcelable. Sin embargo, tengo objetos personalizados y esos objetos tienen ArrayList
atributos de otros objetos personalizados que he creado.
Cuál sería la mejor forma de hacer esto?
Respuestas:
Puede 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 hacerlo 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 Intent
este tipo y recuperar este objeto en la actividad de destino.
intent.putExtra("student", new Student("1","Mike","6"));
Aquí, el alumno es la clave que necesitaría para desempaquetar los datos del paquete.
Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");
Este ejemplo muestra solo String
tipos. Pero, puede parcelar cualquier tipo de datos que desee. Pruébalo.
EDITAR: Otro ejemplo , sugerido por Rukmal Dias .
writeToParcel
método?
Aquí hay un sitio web para crear una Clase Parcelable a partir de su clase creada:
IntelliJ IDEA y Android Studio tienen complementos para esto:
Estos complementos generan código repetitivo parcelable de Android basado en los campos de la clase.
Android Parcelable code generator
public class Sample {
int id;
String name;
}
File > Settings... > Plugins
y haga clic en el Browse repositories...
botón.
Simplemente anota un POJO con una anotación especial y la biblioteca hace el resto.
¡Advertencia!
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 el código de intercambio en caliente (es decir, jRebel, Instant Run).
Pros:
Contras:
¡Advertencia!
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 se pueden encontrar errores de símbolo (JDK 8) .
Hrisey está basado 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}"
Consulte aquí los tipos compatibles. El ArrayList
está entre ellos.
Instale un complemento - Hrisey xor Lombok * - para su IDE y comience a usar sus increíbles funciones.
* No habilite los complementos de Hrisey y Lombok juntos o recibirá un error durante el inicio de IDE.
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 mediante la Parcels
clase de utilidad utilizando
public static <T> Parcelable wrap(T input);
Para desreferenciar @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 README los tipos de atributos admitidos .
AutoParcel es una extensión de 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 es un procesador de anotaciones que genera automáticamente código repetitivo parcelable seguro para Kotlin y Java. PaperParcel admite clases de datos de Kotlin, AutoValue de Google a través de una extensión de AutoValue o simplemente objetos Java Bean normales.
Ejemplo de uso de documentos .
Anote su clase de datos con @PaperParcel
, implemente PaperParcelable
y agregue una instancia estática de JVM, por PaperParcelable.Creator
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 usuarios de Kotlin, vea Uso de Kotlin ; Para usuarios de AutoValue, consulte Uso de AutoValue .
ParcelableGenerator (README está escrito en chino y no lo entiendo. Las contribuciones a esta respuesta de desarrolladores de habla inglesa-china 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 anotaciones en combinación con Android Studio.
Es muy fácil, puede usar un complemento 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];
}
};}
Ahora puede usar la biblioteca Parceler para convertir cualquier clase personalizada en parcelable. Simplemente anote su clase POJO con @Parcel . p.ej
@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 Ejemplo y envolver paquetes y enviarlos como un paquete a través de la intención. p.ej
Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));
Ahora para obtener un objeto de clase personalizada solo use
Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
Android parcable tiene algunas cosas únicas. Esos se dan a continuación:
Ejemplo: para hacer una clase Parceble, debe implementar Parceble. Percable tiene 2 métodos:
int describeContents();
void writeToParcel(Parcel var1, int var2);
Supongamos que tiene una clase Persona y tiene 3 campos, nombre, apellido y edad. Después de implementar la interfaz Parceble. esta interfaz se muestra a continuación:
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
private String firstName;
private String lastName;
private int age;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(firstName);
parcel.writeString(lastName);
parcel.writeInt(age);
}
}
Aquí writeToParcel
método estamos escribiendo / agregando datos en Parcel en un pedido. Después de esto, debemos agregar el siguiente código para leer los datos del paquete:
protected Person(Parcel in) {
firstName = in.readString();
lastName = in.readString();
age = in.readInt();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
Aquí, la clase Persona toma un paquete y obtiene datos en el mismo orden durante la escritura.
Ahora durante la intención getExtra
y el putExtra
código se da a continuación:
Poner en Extra :
Person person=new Person();
person.setFirstName("First");
person.setLastName("Name");
person.setAge(30);
Intent intent = new Intent(getApplicationContext(), SECOND_ACTIVITY.class);
intent.putExtra()
startActivity(intent);
Obtenga extra:
Person person=getIntent().getParcelableExtra("person");
La clase de persona completa se da a continuación :
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
private String firstName;
private String lastName;
private int age;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(firstName);
parcel.writeString(lastName);
parcel.writeInt(age);
}
protected Person(Parcel in) {
firstName = in.readString();
lastName = in.readString();
age = in.readInt();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
Hope this will help you
Thanks :)
Crear clase Parcelable sin complemento en Android Studio
implementa Parcelable en su clase y luego coloca el cursor en "Implementa Parcelable" y presiona Alt+Enter
y selecciona Add Parcelable implementation
(ver imagen). Eso es.
Poner:
bundle.putSerializable("key",(Serializable) object);
Llegar:
List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));
ClassCastException
si el objeto no se implementa Serializable
.