web-dev-qa-db-fra.com

Comment puis-je rendre mes objets personnalisés Parcelable?

J'essaye de rendre mes objets Parcelable. Cependant, j'ai des objets personnalisés et ces objets ont les attributs ArrayList d'autres objets personnalisés que j'ai créés.

Quelle serait la meilleure façon de faire cela?

327
Jean Jimenez

Vous pouvez trouver quelques exemples de ceci ici , ici (le code est pris ici) , et ici .

Vous pouvez créer une classe POJO pour cela, mais vous devez ajouter du code supplémentaire pour la rendre Parcelable. Regardez l'implémentation.

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];
           }
       };
   }

Une fois que vous avez créé cette classe, vous pouvez facilement passer des objets de cette classe à travers le Intent comme ceci et récupérer cet objet dans l'activité cible.

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

Ici, l’étudiant est la clé dont vous auriez besoin pour annuler l’identification des données du paquet.

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

Cet exemple montre uniquement les types String. Mais, vous pouvez envoyer n'importe quel type de données. Essaye le.

EDIT: Un autre exemple , suggéré par Rukmal Dias .

425
fiction

Voici un site Web pour créer une classe colisable à partir de votre classe créée:

http://www.parcelabler.com/

186
francisco_ssb

IntelliJ IDEA et Android Studio ont des plugins pour cela:

Ces plug-ins génèrent Android Parcelable code code général basé sur les champs de la classe.

Plugin demo

110
naXa

1. Importer Android Parcelable code generator

enter image description here

2. Créer une classe

public class Sample {
    int id;
    String name;
}

3. Générer> Colisable à partir du menu

enter image description hereenter image description here

Terminé.

54
itiskj

Comment? Avec des annotations.

Vous annotez simplement un POJO avec une annotation spéciale et la bibliothèque fait le reste.

Attention!

Je ne suis pas sûr que Hrisey, Lombok et d'autres bibliothèques de génération de code soient compatibles avec le nouveau système de construction d'Android. Ils peuvent ou non jouer correctement avec le code d'échange à chaud (c'est-à-dire jRebel, Instant Run).

Avantages:

  • Les bibliothèques de génération de code vous évitent le code source standard.
  • Les annotations rendent votre classe belle.

Les inconvénients:

  • Cela fonctionne bien pour les classes simples. Faire une classe complexe parcellaire peut être délicat.
  • Lombok et AspectJ ne jouent pas bien ensemble. [détails]
  • Voir mes avertissements.

Hrisey

Attention!

Hrisey a un problème connu avec Java 8 et ne peut donc pas être utilisé pour le développement Android de nos jours. Voir # 1 Impossible de trouver des erreurs de symbole (JDK 8) .

Hrisey est basé sur Lombok . Classe parcellaire utilisant Hrisey :

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

Maintenant, vous n'avez pas besoin d'implémenter de méthodes d'interface Parcelable. Hrisey générera tout le code requis pendant la phase de prétraitement.

Dépendances Hrisey dans Gradle:

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

Voir ici pour les types supportés. La ArrayList est parmi eux.

Installez un plugin - Hrisey xor Lombok * - pour votre IDE et commencez à utiliser ses étonnantes fonctionnalités!

enter image description here
* N'activez pas les plug-ins Hrisey et Lombok ensemble, sinon vous obtiendrez une erreur lors du lancement de IDE.


Colisier

Classe parcellable utilisant Parceler :

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

Pour utiliser le code généré, vous pouvez référencer la classe générée directement ou via la classe d’utilitaires Parcels à l’aide de

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

Pour déréférencer le @Parcel, appelez simplement la méthode suivante de Parcels class

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

Dépendances Parceler in Gradle:

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

Regardez dans README pour prendre en charge types d'attribut .


AutoParcel

AutoParcel est une extension AutoValue qui permet la génération de valeurs pouvant être parcellisées.

Ajoutez simplement implements Parcelable à votre @AutoValue modèles annotés:

@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 dans le fichier de génération 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 est un processeur d'annotation qui génère automatiquement du code standard multiplexé, conforme au type, pour Kotlin et Java. PaperParcel prend en charge les classes de données Kotlin, AutoValue de Google via une extension AutoValue, ou simplement des objets bean Java ordinaires.

Exemple d'utilisation de docs .
Annotez votre classe de données avec @PaperParcel, implémentez PaperParcelable et ajoutez une instance statique JVM de PaperParcelable.Creator par exemple:

@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;
    }
}

Pour les utilisateurs de Kotlin, voir tilisation de Kotlin ; Pour les utilisateurs d'AutoValue, voir tilisation d'AutoValue .


ParcelableGenerator

ParcelableGenerator (README est écrit en chinois et je ne le comprends pas. Toute contribution des développeurs parlant anglais et chinois est la bienvenue)

Exemple d'utilisation 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;
    }

}

Le plugin Android-apt vous aide à utiliser les processeurs d'annotation en combinaison avec Android Studio.

21
naXa

J'ai trouvé le moyen le plus simple de créer la classe Parcelable

enter image description here

7
Rjz Satvara

C'est très simple, vous pouvez utiliser un plugin sur Android studio pour créer des objets 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];
    }
};}
1
App-SoftwareFactory

Android parcable a des choses uniques. Ceux-ci sont donnés ci-dessous:

  1. Vous devez lire Parcel dans le même ordre que celui où vous avez mis les données sur le colis.
  2. Le colis sera vide après lecture du colis. C'est-à-dire si vous avez 3 données sur votre colis. Ensuite, après avoir lu 3 fois, le colis sera vide.

Exemple: Pour faire une classe Parceble, elle doit être implémentée Parceble. Percable a 2 méthodes:

int describeContents();
void writeToParcel(Parcel var1, int var2);

Supposons que vous ayez une classe Person et que celle-ci ait 3 champs, prénom, nom et âge. Après avoir implémenté l'interface Parceble. cette interface est donnée ci-dessous:

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);
    }

}

Ici writeToParcel méthode nous écrivons/ajoutons des données sur Parcel dans un ordre. Après cela, nous devons ajouter le code ci-dessous pour lire les données de parcelle:

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];
        }
    };

Ici, la classe Personne prend un colis et obtient des données dans le même ordre lors de l'écriture.

Maintenant, pendant l'intention, les codes getExtra et putExtra sont donnés ci-dessous:

mettre 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); 

Obtenez Extra:

Person person=getIntent().getParcelableExtra("person");

La classe de personne à part entière est donnée ci-dessous:

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 :)
0
Md. Sajedul Karim

Vous pouvez maintenant utiliser la bibliothèque Parceler pour convertir votre classe personnalisée en parcelle. Annotez simplement votre classe POJO avec @ Parcel . par exemple.

    @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; }
}

vous pouvez créer un objet de la classe Example et parcourir les parcelles, puis l'envoyer comme un paquet via l'intention. par exemple

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

Maintenant, pour obtenir un objet Custom Class, utilisez simplement

Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
0
Shubham Shukla