897 votes

Comment envoyer un objet d'une activité Android à une autre en utilisant les intents ?

Comment puis-je passer un objet d'un type personnalisé d'une Activité à un autre en utilisant le putExtra() de la classe Intento ?

0 votes

@UMMA - vous n'avez pas besoin de continuer à marquer vos questions comme "Wiki communautaire". Jetez un coup d'œil ici : meta.stackexchange.com/questions/11740/

1 votes

@Paresh : le lien que vous avez fourni est cassé. Pourriez-vous fournir une alternative ?

0 votes

782voto

fiXedd Points 21644

Si vous ne faites que passer des objets, alors Parcelable a été conçu pour cela. Son utilisation demande un peu plus d'efforts que celle de la sérialisation native de Java, mais elle est beaucoup plus rapide (et je dis bien beaucoup), WAY plus rapide).

Dans la documentation, un exemple simple de mise en œuvre est donné :

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

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

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

Notez que si vous avez plus d'un champ à extraire d'une parcelle donnée, vous devez le faire dans l'ordre dans lequel vous les avez placés (c'est-à-dire selon une approche FIFO).

Une fois que vous avez vos objets, implémentez Parcelable il s'agit juste de les mettre dans votre Intentions con putExtra() :

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

Ensuite, vous pouvez les retirer avec getParcelableExtra() :

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

Si votre classe d'objets implémente Parcelable et Serializable, assurez-vous que vous effectuez un cast vers l'un des éléments suivants :

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

15 votes

Comment cela serait-il mis en œuvre lorsque mData est un objet (par exemple JSONObject) et non un int ?

0 votes

Parcel dispose d'autres méthodes pour écrire des types de données tels que les chaînes de caractères. Dans le cas d'un JSONObject, vous pouvez le transformer en JSON et l'écrire sous forme de chaîne. Si l'objet est Serializable et que vous n'avez pas l'accès pour le rendre Parcelable, peut-être que vous pourriez le sérialiser et le désérialiser lorsque vous dé-parcelez l'objet de niveau supérieur ? Je n'ai jamais fait ça avant, c'est juste une supposition.

313 votes

Pourquoi ne peut-on pas simplement passer l'objet sans tout ça ? Nous voulons passer un objet qui est déjà en mémoire.

205voto

David Hedlund Points 66192

Vous devrez sérialiser votre objet dans une sorte de représentation de chaîne de caractères. Une représentation possible de la chaîne est JSON, et l'une des façons les plus faciles de sérialiser vers/depuis JSON dans Android, si vous voulez mon avis, est par le biais de Google GSON .

Dans ce cas, vous mettez simplement la valeur de retour de la chaîne de caractères de (new Gson()).toJson(myObject); et récupérer la valeur de la chaîne et utiliser fromJson pour le transformer en votre objet.

Cependant, si votre objet n'est pas très complexe, il se peut que cela ne vaille pas la peine, et vous pourriez envisager de passer les valeurs séparées de l'objet à la place.

19 votes

Je suppose que c'est parce que la réponse de fiXedd résout le même problème sans utiliser de bibliothèques externes, d'une manière qui est tout simplement tellement préférable, que personne ne devrait jamais avoir de raison de suivre la solution que j'ai fournie (sans connaître, à l'époque, la brillante solution de fiXedd).

5 votes

Je pense que c'est correct. De plus, JSON est un protocole plus approprié pour le client/serveur et non pour le thread-to-thread.

18 votes

Ce n'est pas nécessairement une mauvaise idée, surtout que Gson est beaucoup plus simple à utiliser que d'implémenter parcelable pour tous les objets que vous voulez envoyer.

160voto

Sridhar Points 506

Vous pouvez envoyer un objet sérialisable par le biais de l'intention

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);

//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
}

2 votes

Vous pouvez également envoyer des objets "colisables" par le biais de l'intention.

6 votes

"Serializable est comiquement lent sur Android. En fait, il est pratiquement inutile dans de nombreux cas". stackoverflow.com/questions/5550670/

0 votes

Si l'activité est déjà en cours, faut-il faire startActivity(i) ; ? Je veux dire, est-ce que je peux faire activité A appelez activité B et qui renvoie des données à activité A ? Je suis confus ?

70voto

Peter Ajtai Points 26377

Pour les situations où vous savez que vous allez transmettre des données au sein d'une application, utilisez des "globaux" (comme les classes statiques).

Ici est ce que Dianne Hackborn (hackbod - un ingénieur logiciel de Google Android) s'est exprimé sur le sujet :

Dans les situations où vous savez que les activités sont exécutées dans le même processus, vous pouvez simplement partager les données par le biais des globales. Par exemple, vous pourriez avoir un global HashMap<String, WeakReference<MyInterpreterState>> et lorsque vous créez un nouveau MyInterpreterState, vous lui donnez un nom unique unique et le mettre dans la carte de hachage ; pour envoyer cet état à une autre activité activité, il suffit de mettre le nom unique dans la carte de hachage et lorsque la seconde activité est lancée, elle peut récupérer le MyInterpreterState dans la carte de hachage. la carte de hachage avec le nom qu'elle reçoit.

25 votes

Oui, j'ai trouvé étrange que l'on nous donne ces Intents à utiliser, et qu'ensuite un ingénieur de haut niveau nous dise d'utiliser des globaux pour nos données. Mais ça vient directement de la bouche du cheval.

1 votes

La référence faible ici ne serait-elle pas victime du garbage collection ?

1 votes

@uLYsseus je pense que c'est l'idée, une fois que vous avez fini avec eux dans les activités ... donc quand les activités pertinentes sont détruites, il permettra de gc.

50voto

Pedro Romão Points 143

Votre classe doit implémenter Serializable ou Parcelable.

public class MY_CLASS implements Serializable

Une fois que c'est fait, vous pouvez envoyer un objet sur putExtra.

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Pour obtenir des extras, il vous suffit de faire

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

Si votre classe implémente Parcelable, utilisez la fonction suivante

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

J'espère que cela vous aidera :D

6 votes

Votre classe doit implémenter Serializable a tort. La classe peut implémenter Parcelable par exemple.

0 votes

Quelle est la différence entre Parcelable et Serializable @Kernald ? En termes de temps de traitement, est-ce que c'est plus lent / ce n'est pas une bonne pratique ou autre chose ?

0 votes

Alors que Serializable est une interface standard de Java, Parcelable est spécifique à Android. En termes de performances, Parcelable est plus efficace : developerphil.com/parcelable-vs-serializable

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