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


338

J'essaie de rendre mes objets parcellables. Cependant, j'ai des objets personnalisés et ces objets ont des ArrayListattributs d'autres objets personnalisés que j'ai créés.

Quelle serait la meilleure façon de faire cela?

Réponses:


432

Vous pouvez en trouver des exemples 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 le faire Parcelable. Jetez un oeil à la mise en œuvre.

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 par le biais de Intentcelui-ci 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 décompresser les données du bundle.

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

Cet exemple affiche uniquement les Stringtypes. Mais, vous pouvez répartir tout type de données que vous souhaitez. Essaye le.

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


@Rukmal Dias 10x. En fait, je dois modifier ma réponse et ajouter du code, car ces liens ne seront plus actifs un jour à l'avenir.
fiction

16
OP demandant comment passer des objets personnalisés pas une chaîne régulière. Tout le monde peut passer des cordes régulières. Pourriez-vous expliquer COMMENT le créer avec CUSTOM OBJECT

Dois-je réellement implémenter les parties d'encodage / décodage si je les envoie uniquement à l'aide de LocalBroadcastManager? Est-ce suffisant pour implémenter Parcelable et le mettre en extra?
JohnyTex

Pourquoi utilisez-vous un tableau de chaînes au lieu de simplement écrire les chaînes successivement?
Quentin Roy

L'ordre des membres lors de la création du tableau de chaînes à l'intérieur de la writeToParcelméthode est-il important?
Prakhar Mohan Srivastava



56

1. Importer Android Parcelable code generator

entrez la description de l'image ici

2. Créez une classe

public class Sample {
    int id;
    String name;
}

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

entrez la description de l'image ici entrez la description de l'image ici

Terminé.


7
Pour ceux qui ne savent pas où se trouve la boîte de dialogue Parcourir les référentiels: File > Settings... > Pluginset cliquez sur le Browse repositories...bouton.
DaedalusAlpha

Merci, beaucoup aidé!
Strahinja Ajvaz,

21

Comment? Avec annotations.

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

Avertissement!

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 (par exemple jRebel, Instant Run).

Avantages:

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

Les inconvénients:

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

Hrisey

Avertissement!

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 les erreurs de symbole (JDK 8) .

Hrisey est basé sur Lombok . Classe parcelable avec Hrisey :

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

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

Hrisey dans les dépendances de Gradle:

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

Voir ici pour les types pris en charge. Le ArrayListest parmi eux.

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

entrez la description de l'image ici
* N'activez pas les plugins Hrisey et Lombok ensemble ou vous obtiendrez une erreur lors du lancement de l'IDE.


Colisier

Classe parcelable 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 Parcelsclasse utilitaire en utilisant

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

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

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

Parceler dans les dépendances Gradle:

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

Recherchez dans README les types d'attributs pris en charge .


AutoParcel

AutoParcel est une AutoValue extension qui permet la génération de valeurs Parcelable.

Ajoutez simplement implements Parcelableà vos @AutoValuemodè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 construction 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 passe-partout Parcelable de type sécurisé pour Kotlin et Java. PaperParcel prend en charge les classes de données Kotlin, AutoValue de Google via une extension AutoValue, ou tout simplement des objets de bean Java standard.

Exemple d'utilisation de documents .
Annotez votre classe de données avec @PaperParcel, implémentez PaperParcelableet ajoutez une instance statique JVM, PaperParcelable.Creatorpar 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 Utilisation de Kotlin ; Pour les utilisateurs d'AutoValue, voir Utilisation d'AutoValue .


ParcelableGenerator

ParcelableGenerator (README est écrit en chinois et je ne le comprends pas. Les contributions à cette réponse de développeurs anglophones sont les bienvenues)

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 aide à travailler avec les processeurs d'annotation en combinaison avec Android Studio.


7

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

entrez la description de l'image ici


1
cela fonctionne bien pour les petites données, mais si nous prenons des données complexes, cela ne fonctionnera pas
Manohar Reddy

1

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

4
Quel plugin voulez-vous dire?
naXa

0

Vous pouvez maintenant utiliser la bibliothèque Parceler pour convertir vos classes personnalisées en parcelable. 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 passer par Parcels et l'envoyer en tant que bundle par intention. par exemple

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

Maintenant, pour obtenir un objet de classe personnalisé, utilisez simplement

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

0

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

  1. Vous devez lire Parcel comme la même commande où vous mettez des données sur le colis.
  2. Le colis sera vide après lecture du colis. C'est 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, il faut implémenter Parceble. Percable a 2 méthodes:

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

Supposons que vous ayez une classe Person et qu'elle ait 3 champs, firstName, lastName et age. 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);
    }

}

Voici la writeToParcelméthode que nous écrivons / ajoutons des données sur le colis dans une commande. Après cela, nous devons ajouter un code ci-dessous pour lire les données du colis:

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 Person prend un colis et obtient les données dans un même ordre lors de l'écriture.

Maintenant, pendant l'intention getExtraet le putExtracode est donné ci-dessous:

Mettez 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 Personne Complète 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

Créer une classe Parcelable sans plugin dans Android Studio

implémente Parcelable dans votre classe, puis placez le curseur sur "implémente Parcelable" et appuyez sur Alt+Enteret sélectionnez Add Parcelable implementation(voir image). c'est tout.

entrez la description de l'image ici


-3

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

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


3
Cela conduira à ClassCastExceptionsi l'objet n'est pas implémenté Serializable.
naXa

1
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir et que ces personnes ne connaissent peut-être pas les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, cela réduit la lisibilité du code et des explications!
Ashish Ahuja
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.