897 votes

Comment passer un objet d'une activité à une autre sur Android ?

J'essaie de travailler sur l'envoi d'un objet de mon client d'une classe Activity et l'afficher dans un autre Activity .

Le code de la classe client :

public class Customer {

    private String firstName, lastName, Address;
    int Age;

    public Customer(String fname, String lname, int age, String address) {

        firstName = fname;
        lastName = lname;
        Age = age;
        Address = address;
    }

    public String printValues() {

        String data = null;

        data = "First Name :" + firstName + " Last Name :" + lastName
        + " Age : " + Age + " Address : " + Address;

        return data;
    }
}

Je veux envoyer son objet d'un Activity à une autre et ensuite afficher les données sur l'autre Activity .

Comment puis-je y parvenir ?

0 votes

J'avais l'habitude de définir l'objet comme Pacelable ou Serializable, mais chaque fois que j'ajoute d'autres variables, je dois tout ajouter aux fonctions pour obtenir et définir pour Pacelable ou Serializable. J'ai donc créé DataCache pour transférer entre les activités et les fragments. github.com/kimkevin/AndroidDataCache C'est très facile de transférer un objet.

0 votes

J'ai créé un wrapper TrackedReference<Any> qui est parcellisable et sérialisable sans nécessiter de marshaling (sérialisation ou parcellisation) pour le type sous-jacent : stackoverflow.com/a/64944753/3405387

0 votes

Pourquoi ne pas simplement utiliser des variables statiques et y accéder à partir d'une autre activité, sans avoir à les recréer en mémoire et aussi la stérilisation de l'objet peut consommer des ressources.

977voto

Samuh Points 16564

Une option pourrait consister à laisser votre classe personnalisée implémenter la fonction Serializable puis vous pouvez transmettre des instances d'objets dans l'extra d'intention en utilisant l'interface putExtra(Serializable..) variante de la Intent#putExtra() méthode.

Code réel :

Dans votre classe de modèle/objet personnalisée :

public class YourClass implements Serializable {

Dans les autres classes où l'on utilise le modèle/la classe personnalisé(e) :

//To pass:
intent.putExtra("KEY_NAME", myObject);

myObject est de type "YourClass". Ensuite, pour récupérer à partir d'une autre activité, utilisez getSerializableExtra pour récupérer l'objet en utilisant le même nom de clé. Et le typecast vers YourClass est nécessaire :

// To retrieve object in second Activity
myObject = (YourClass) getIntent().getSerializableExtra("KEY_NAME");

Remarque : assurez-vous que chaque classe imbriquée de votre classe principale personnalisée a mis en œuvre l'interface Serializable pour éviter toute exception de sérialisation. Par exemple :

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}

1 votes

Je suis dans la même situation. Après avoir implémenté Serializable, dois-je faire quelque chose de spécial dans ma classe, dois-je implémenter certaines méthodes ?

129 votes

@OD : Pour ma défense, je n'ai jamais dit que c'était la meilleure option ; le PO a juste demandé des alternatives et j'en ai suggéré une. Merci quand même.

84 votes

Pourquoi Serializable n'est pas une bonne option ? C'est une interface bien connue, il y a de fortes chances que les classes des autres l'implémentent déjà (ArrayList, par exemple, est déjà Serializable). Pourquoi devriez-vous modifier vos objets de données et ajouter du code supplémentaire simplement pour les faire passer d'une classe à une autre ? Cela semble être une mauvaise conception. Je peux imaginer qu'il peut y avoir un impact sur les performances à un certain niveau, mais je pense que dans 99% des cas, les gens passent de petites quantités de données, et ils ne s'en soucient pas. Plus simple et portable est parfois mieux, aussi.

343voto

Mustafa Güven Points 2316

Implémentez votre classe avec Serializable. Supposons qu'il s'agisse de votre classe d'entité :

import java.io.Serializable;

@SuppressWarnings("serial") //With this annotation we are going to hide compiler warnings
public class Deneme implements Serializable {

    public Deneme(double id, String name) {
        this.id = id;
        this.name = name;
    }

    public double getId() {
        return id;
    }

    public void setId(double id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

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

    private double id;
    private String name;
}

Nous envoyons l'objet appelé dene de l'activité X à l'activité Y. Quelque part dans l'activité X ;

Deneme dene = new Deneme(4,"Mustafa");
Intent i = new Intent(this, Y.class);
i.putExtra("sampleObject", dene);
startActivity(i);

Dans l'activité Y, nous obtenons l'objet.

Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");

C'est tout.

1 votes

C'était vraiment utile pour moi. Merci... Mais lors de la réception de l'objet passé, la syntaxe devrait être [ Deneme dene = (Deneme)i.getSerializableExtra("sampleObject") ; ] .... C'est bien cela ? ??

1 votes

@MustafaGüven Mais j'obtiens classCastException: java.lang.Long en le faisant. Pouvez-vous expliquer pourquoi ?

0 votes

Il n'y a aucun rapport avec ma réponse. C'est une chose très différente que vous obtenez. Pourriez-vous partager vos codes ?

133voto

SohailAziz Points 1873
  • Utilisation de l'approche globale les variables statiques ne constituent pas une bonne ingénierie logicielle pratique.
  • Convertir les champs d'un objet en primitives Les types de données peuvent être un travail trépidant .
  • Utilisation de sérialisable, c'est bien, mais ce n'est pas efficace en termes de performances. sur la plateforme Android.
  • Parcelable est spécifiquement conçu pour Android et vous devriez l'utiliser. Voici un exemple simple : Passage d'objets personnalisés entre les activités Android

Vous pouvez générer du code Parcelable pour votre classe en utilisant ceci site .

4 votes

Que faire si mon objet contient des Arraylist imbriquées ?

11 votes

Peut-être, mais il faut vraiment prendre les "performances" avec des pincettes. Si cela se fait au prix de la mise en œuvre Parcelable alors je préfère garder mes classes POJO agnostiques Android et utiliser Serializable .

0 votes

Je ne suis pas d'accord pour que vous utilisiez Parcelable. Un simple pattern BUS est beaucoup plus efficace à l'exécution et permet de gagner un temps fou de développement.

100voto

Ads Points 2567

En appelant une activité

Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);

Dans toClass.java recevez l'activité par

Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");

S'il vous plaît assurez-vous que la classe du client implémente parcelable

public class Customer implements Parcelable {

    private String firstName, lastName, address;
    int age;

    /* all your getter and setter methods */

    public Customer(Parcel in ) {
        readFromParcel( in );
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public LeadData createFromParcel(Parcel in ) {
            return new Customer( in );
        }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(firstName);
        dest.writeString(lastName);
        dest.writeString(address);
        dest.writeInt(age);
    }

    private void readFromParcel(Parcel in ) {

        firstName = in .readString();
        lastName  = in .readString();
        address   = in .readString();
        age       = in .readInt();
    }

0 votes

Adhavan, j'ai une question. Lorsque vous créez la première classe Intent, vous passez dans fromClass.this comme premier argument. Y a-t-il un moyen de récupérer cet objet dans la classe d'activité réceptrice ?

1 votes

Miliu, fromClass fr = (fromClass) getParent() ; est-ce ce dont vous aviez besoin ?

0 votes

Adhava, j'ai fait ça, mais le fr est nul. Une idée de la raison ?

92voto

Steven Mark Ford Points 342

D'après mon expérience, il existe trois solutions principales, chacune ayant ses inconvénients et ses avantages :

  1. Mise en œuvre de Parcelable

  2. Mise en œuvre de Serializable

  3. Utiliser une bibliothèque légère de bus d'événements (par exemple, EventBus de Greenrobot ou Otto de Square).

Parcelable - rapide et standard Android, mais il comporte beaucoup de code passe-partout et nécessite des chaînes codées en dur comme référence lors de l'extraction de valeurs de l'intention (non typée forte).

Serializable - proche de zéro boilerplate, mais c'est l'approche la plus lente et elle nécessite également des chaînes codées en dur lorsque l'on extrait des valeurs de l'intention (non typée fortement).

Bus événementiel - aucun boilerplate, l'approche la plus rapide, et ne nécessite pas de chaînes codées en dur, mais elle nécessite une dépendance supplémentaire (bien que généralement légère, ~40 KB)

J'ai publié une comparaison très détaillée de ces trois approches, y compris des critères d'efficacité.

4 votes

Le lien vers l'article est mort. Toujours disponible sur webarchive : web.archive.org/web/20160917213123/http://…

0 votes

C'est dommage que le lien ne fonctionne plus :(

0 votes

Le problème de l'utilisation du bus d'événements se pose lorsque l'activité cible est recréée en raison d'une rotation, par exemple. Dans ce cas, l'activité cible n'a pas accès à l'objet passé car cet objet a été consommé à partir du bus par un appel précédent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X