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

849

Comment passer un objet d'un type personnalisé d'une activité à une autre en utilisant la putExtra()méthode de la classe Intent ?

UMAR
la source
@UMMA - vous n'avez pas besoin de continuer à marquer vos questions comme "Community Wiki". Jetez un œil ici: meta.stackexchange.com/questions/11740/…
Dave Webb
1
@Paresh: le lien que vous avez fourni est rompu. pourriez-vous plz fournir une alternative?
antiplex
Découvrez cette réponse. stackoverflow.com/questions/8857546/…
Heitor Colangelo
j'ai trouvé une méthode simple et élégante stackoverflow.com/a/37774966/6456129
Yessy

Réponses:

751

Si vous ne faites que passer des objets, Parcelable a été conçu pour cela. Il a besoin d' un peu plus d' effort à l' utilisation que l' utilisation sérialisation natif de Java, mais il est beaucoup plus rapide (et je méchamment, WAY plus rapide).

À partir des documents, un exemple simple de mise en œuvre est:

// 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 dans le cas où vous avez plusieurs champs à récupérer à partir d'une parcelle donnée, vous devez le faire dans le même ordre que vous les avez mis (c'est-à-dire dans une approche FIFO).

Une fois que vos objets sont implémentés, Parcelableil suffit de les mettre dans vos intentions avec 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);
Jeremy Logan
la source
14
Comment cela serait-il implémenté lorsque mData est un objet (par exemple JSONObject) et non un int?
Peter Ajtai
301
Pourquoi ne peut-on pas simplement passer l'objet sans tout cela? Nous voulons passer un objet qui est déjà en mémoire.
ceklock
110
@tecnotron ses applications beacuse sont dans des processus différents et ont des espaces d'adressage mémoire séparés, vous ne pouvez pas simplement envoyer un pointeur (référence) au bloc de mémoire dans votre processus et vous attendre à ce qu'il soit disponible dans un autre processus.
marcinj
12
Que dois-je faire si je ne peux pas rendre la classe de l'objet sérialisable ou parceable?
Amel Jose
11
@ceklock la raison derrière cela est la suivante: lorsque l'activité passe derrière et est ensuite supprimée de la mémoire, puis lorsque l'utilisateur l'ouvre à partir du menu récent, il doit créer l'activité là où elle s'est arrêtée. Il doit s'agir de la même interface utilisateur. L'objet n'est pas dans la mémoire dans ce cas. Mais l'intention est.
tasomaniac
194

Vous devrez sérialiser votre objet en une sorte de représentation sous forme de chaîne. Une représentation de chaîne possible est JSON, et l'un des moyens les plus simples de sérialiser vers / depuis JSON dans Android, si vous me le demandez, est via Google GSON .

Dans ce cas, vous venez de mettre la valeur de retour de (new Gson()).toJson(myObject);la chaîne et de récupérer la valeur de la chaîne et de l'utiliser fromJsonpour la reconvertir en votre objet.

Si votre objet n'est pas très complexe, cependant, il ne vaut peut-être pas la surcharge, et vous pouvez envisager de passer les valeurs séparées de l'objet à la place.

David Hedlund
la source
19
Je suppose que la réponse de fiXedd résout le même problème sans l'utilisation de bibliothèques externes, d'une manière qui est tellement préférable, que personne ne devrait jamais avoir de raison de suivre la solution que j'ai fournie (ignorant, à l'époque, de La solution brillante de fiXedd)
David Hedlund
5
Je pense que c'est exact. De plus, JSON est un protocole plus approprié pour le client / serveur et non pas thread-to-thread.
mobibob
16
Pas nécessairement une mauvaise idée, surtout. car Gson est beaucoup plus simple à utiliser qu'à implémenter parcelable pour tous les objets que vous souhaitez envoyer.
uvesten
7
comme j'utilise gson dans mon application, c'est une manière vraiment simple et agréable!
Lars
16
Belle réponse, même si une solution complète serait String s = (new Gson().toJson(client));et ensuiteCli client = new Gson().fromJson(s, Cli.class);
Joaquin Iurchuk
155

Vous pouvez envoyer un objet sérialisable par 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 {
} 
Sridhar
la source
2
vous pouvez également envoyer des objets parcellaires par intention.
tony gil
6
"La sérialisation est comiquement lente sur Android. Borderline inutile dans de nombreux cas en fait." regardez stackoverflow.com/questions/5550670/…
Seraphim's
que faire si l'activité est déjà en cours, faut-il faire startActivity (i); ? Je veux dire, puis-je faire l' activité A appeler l' activité B , et qui renvoie des données à l' activité A ? suis-je confus?
Francisco Corrales Morales,
3
@ Les performances de Seraphim sont importantes si vous sérialisez beaucoup d'objets, mais l'utilisateur ne remarquera pas si la sérialisation d'un objet prend 1 ms ou 10 ms. Si une intention supplémentaire est déjà Serializablemais pas Parcelable, cela vaut rarement la peine de le faire Parcelable.
Kevin Krumwiede
67

Pour les situations où vous savez que vous allez transmettre des données dans une application, utilisez des «globaux» (comme des classes statiques)

Voici ce que Dianne Hackborn (hackbod - un ingénieur logiciel Google Android) avait à dire à ce sujet:

Pour les situations où vous savez que les activités s'exécutent dans le même processus, vous pouvez simplement partager des données via des globaux. Par exemple, vous pouvez avoir un global HashMap<String, WeakReference<MyInterpreterState>> et lorsque vous créez un nouveau MyInterpreterState, attribuez-lui un nom unique et placez-le dans la carte de hachage; pour envoyer cet état à une autre activité, il suffit de mettre le nom unique dans la carte de hachage et lorsque la deuxième activité est démarrée, il peut récupérer le MyInterpreterState de la carte de hachage avec le nom qu'il reçoit.

Peter Ajtai
la source
25
oui, j'ai trouvé étrange qu'on nous donne ces intentions à utiliser, puis un ingénieur de haut niveau nous a dit de n'utiliser que des globaux pour nos données. Mais là, c'est directement de la bouche des chevaux.
Richard Le Mesurier
1
La faible réfrence ne serait-elle pas ici victime de la collecte des déchets?
uLYsseus
1
@uLYsseus pense que c'est l'idée, une fois que vous en avez terminé avec les activités ... donc quand les activités pertinentes sont détruites, cela lui permettra de gc
Peter Ajtai
1
@RichardLeMesurier Je pensais la même chose, mais j'ai ensuite regardé le post Google Groupes référencé ci-dessus de Dianne Hackborn, et elle mentionne que le seul problème avec les globaux serait vraiment lors de l'utilisation d'intentions implicites (qui peuvent lancer une activité en dehors de votre package) ). Cela a du sens, comme le mentionne Dianne, car ces activités n'auraient probablement aucune connaissance des types personnalisés que vous leur transmettez. Une fois que j'ai lu cela, cela m'a permis de comprendre pourquoi les globaux ne pouvaient pas être une si mauvaise route dans les circonstances, et j'ai pensé que je partagerais au cas où d'autres seraient aussi curieux
BMB
les intentions ont été trop conçues pour que l'intention puisse être transmise à un autre ordinateur. ce qui n'est évidemment pas un bon moyen de faire quoi que ce soit quand vous n'avez en fait qu'un seul processus dans lequel vous vous faufilez. raisons pour lesquelles ce n'est pas bon: utilisation de la mémoire, utilisation du processeur, utilisation de la batterie. le dernier a surtout fait les choix de conception avec des intentions assez perplexes avec le recul. il y a des gens qui insistent sur le fait qu'ils sont une bonne idée, généralement parce que "google l'a dit".
Lassi Kinnunen
49

Votre classe doit implémenter Serializable ou Parcelable.

public class MY_CLASS implements Serializable

Une fois cela fait, vous pouvez envoyer un objet sur putExtra

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Pour obtenir des extras, il suffit de faire

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

Si votre classe implémente l'utilisation de Parcelable ensuite

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

J'espère que ça aide: D

Pedro Romão
la source
6
Votre classe doit implémenter Serializableest faux. La classe peut implémenter Parcelablepar exemple.
Marc Plano-Lesay
quelle est la différence entre Parcelable et Serializable @Kernald? en termes de temps de traitement, est-ce plus lent / pas la meilleure pratique ou quelque chose?
gumuruh
Bien qu'il Serializables'agisse d'une interface Java standard, elle Parcelableest spécifique à Android. En termes de performances, Parcelable est plus efficace: developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay
35

Réponse courte pour un besoin rapide

1. Implémentez votre classe en sérialisable.

Si vous avez des classes internes, n'oubliez pas de les implémenter en Serializable aussi !!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. Mettez votre objet en intention

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3. Et recevez votre objet dans l'autre classe d'activité

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");
Sam
la source
voir ce lien, stackoverflow.com/questions/2139134/…
RejoylinLokeshwaran
Vous pouvez réaliser la même chose en implémentant l'interface Parcelable. L'interface parcelable prend plus de temps à implémenter par rapport à Serializable en raison de la taille du code. Mais il fonctionne plus rapidement que Serializable et utilise moins de ressources.
Kwnstantinos Nikoloutsos
27

si votre classe d'objets implémente Serializable, vous n'avez rien d'autre à faire, vous pouvez passer un objet sérialisable.
c'est ce que j'utilise.

Vlad
la source
24

implémenter sérialisable dans votre classe

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

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

Ensuite, vous pouvez passer cet objet en intention

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

dans la deuxième activité, vous pouvez obtenir des données comme celle-ci

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

Mais lorsque les données deviennent volumineuses, cette méthode sera lente.

Ishan Fernando
la source
16

Vous pouvez utiliser Android BUNDLE pour ce faire.

Créez un bundle à partir de votre classe comme:

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

Passez ensuite ce bundle avec INTENT. Vous pouvez maintenant recréer votre objet de classe en passant un bundle comme

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

Déclarez cela dans votre classe personnalisée et utilisez.

om252345
la source
1
Préférable de diriger la mise en œuvre de Parcelable, à mon humble avis. Bundle implémente Parcelable par lui-même afin que vous ayez toujours le gain de performances tout en évitant tous les problèmes de mise en œuvre vous-même. Au lieu de cela, vous pouvez utiliser des paires clé-valeur pour stocker et récupérer les données qui sont de loin plus robustes que de se fier à un simple ordre.
Risadinha
Parcelable me semble compliqué, dans ma réponse ci-dessus, j'utilise la méthode toBundle de la classe sur son objet afin que l'objet soit converti en bundle, puis nous pouvons utiliser le constructeur pour convertir le bundle en objet de classe.
om252345
Cette solution n'est viable que si vous passez un seul objet à travers une intention.
TheIT
Comme json mais json est léger je pense.
David
L'objet lorsque je le récupère sera-t-il le même objet ou une copie?
Markus
16

Il existe deux façons d'accéder aux variables ou aux objets dans d'autres classes ou activités.

A. Base de données

B. préférences partagées.

C. Sérialisation d'objets.

D. Une classe qui peut contenir des données communes peut s'appeler Common Utilities, cela dépend de vous.

E. Transmission des données via les intentions et l'interface parcelable.

Cela dépend des besoins de votre projet.

UNE. Base de données

SQLite est une base de données Open Source intégrée à Android. SQLite prend en charge les fonctionnalités de base de données relationnelles standard telles que la syntaxe SQL, les transactions et les instructions préparées.

Tutoriels - http://www.vogella.com/articles/AndroidSQLite/article.html

B. Préférences partagées

Supposons que vous souhaitiez stocker le nom d'utilisateur. Il y aura donc maintenant deux choses: un nom d' utilisateur clé , Value Value.

Comment conserver

 // Create an object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
 //now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();
 //put your value
 editor.putString("userName", "stackoverlow");

 //commits your edits
 editor.commit();

En utilisant putString (), putBoolean (), putInt (), putFloat (), putLong (), vous pouvez enregistrer le dtatype souhaité.

Comment aller chercher

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

http://developer.android.com/reference/android/content/SharedPreferences.html

C. Sérialisation des objets

La sérialisation d'objets est utilisée si nous voulons enregistrer un état d'objet pour l'envoyer sur le réseau ou si vous pouvez également l'utiliser pour votre usage.

Utilisez des java beans et stockez-le comme l'un de ses champs et utilisez des getters et setter pour cela

JavaBeans sont des classes Java qui ont des propriétés. Considérez les propriétés comme des variables d'instance privées. Puisqu'ils sont privés, le seul moyen d'y accéder depuis l'extérieur de leur classe est via les méthodes de la classe. Les méthodes qui modifient la valeur d'une propriété sont appelées méthodes setter et les méthodes qui récupèrent la valeur d'une propriété sont appelées méthodes getter.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }


}

Définissez la variable dans votre méthode de messagerie à l'aide de

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

Utilisez ensuite l'objet Serialzation pour sérialiser cet objet et dans votre autre classe désérialiser cet objet.

Dans la sérialisation, un objet peut être représenté comme une séquence d'octets qui inclut les données de l'objet ainsi que des informations sur le type de l'objet et les types de données stockées dans l'objet.

Une fois qu'un objet sérialisé a été écrit dans un fichier, il peut être lu dans le fichier et désérialisé, c'est-à-dire que les informations de type et les octets qui représentent l'objet et ses données peuvent être utilisés pour recréer l'objet en mémoire.

Si vous voulez un tutoriel pour cela se référer à ce lien

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

Obtenir une variable dans d'autres classes

D. CommonUtilities

Vous pouvez créer une classe par vous-même qui peut contenir des données communes dont vous avez souvent besoin dans votre projet.

Échantillon

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Transmission de données par des intentions

Veuillez vous référer à ce tutoriel pour cette option de transmission de données.

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/

Nikhil Agrawal
la source
Bon tutoriel que vous mentionnez dans (E) sur le passage de données via Intents.
remrick
15

Merci pour l'aide parcelable mais j'ai trouvé une autre solution optionnelle

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

Dans l'activité un

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

Récupérer des données dans l'activité 2

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }
1140237
la source
1
bonne réponse, mais augmentez vos normes de codage ... +1 pour avoir apporté Serializable dans la compétition, mais les Parcellables sont beaucoup plus rapides ...
Amit
13

J'utilise Gson avec son API si puissante et simple pour envoyer des objets entre les activités,

Exemple

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

2 fonctions vous les ajoutez aux objets que vous souhaitez envoyer

Usage

Envoyer un objet de A vers B

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

Recevoir en B

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

Je l'utilise presque dans tous les projets que je fais et je n'ai aucun problème de performance.

MBH
la source
Merci, cela m'a sauvé des heures de surcompensation.
Hristo Stoyanov
10

J'ai lutté avec le même problème. Je l'ai résolu en utilisant une classe statique, en stockant toutes les données que je veux dans un HashMap. En plus, j'utilise une extension de la classe Activity standard où j'ai remplacé les méthodes onCreate un onDestroy pour faire le transport de données et l'effacement des données cachés. Certains paramètres ridicules doivent être modifiés, par exemple la gestion de l'orientation.

Annotation: ne pas fournir d'objets généraux à transmettre à une autre activité est une douleur dans le cul. C'est comme se tirer une balle dans le genou et espérer gagner un 100 mètres. "Parcable" n'est pas un substitut suffisant. Ça me fait rire ... Je ne veux pas implémenter cette interface dans mon API sans technologie, moins je veux introduire une nouvelle couche ... Comment se fait-il que nous soyons dans la programmation mobile si loin de paradigme moderne ...

oopexpert
la source
9

Dans votre première activité:

intent.putExtra("myTag", yourObject);

Et dans votre deuxième:

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

N'oubliez pas de rendre votre objet personnalisé sérialisable:

public class myCustomObject implements Serializable {
...
}
Rudi
la source
Parcelable est meilleur que Serializable! Évitez d'utiliser Serializable dans votre code Android!
Filipe Brito
7

Une autre façon de procéder consiste à utiliser l' Applicationobjet (android.app.Application). Vous définissez cela dans votre AndroidManifest.xmlfichier comme:

<application
    android:name=".MyApplication"
    ...

Vous pouvez ensuite l'appeler à partir de n'importe quelle activité et enregistrer l'objet dans la Applicationclasse.

Dans la FirstActivity:

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

Dans SecondActivity, faites:

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

C'est pratique si vous avez des objets qui ont une portée au niveau de l'application, c'est-à-dire qu'ils doivent être utilisés dans toute l'application. La Parcelableméthode est encore meilleure si vous voulez un contrôle explicite sur la portée de l'objet ou si la portée est limitée.

Cela évite cependant l'utilisation de Intentstout à fait. Je ne sais pas si ça te va. Une autre façon dont j'ai utilisé cela est d'avoir des intidentifiants d'objets envoyés via des intentions et de récupérer les objets que j'ai dans Maps dans l' Applicationobjet.

Saad Farooq
la source
1
Ce n'est pas la bonne façon de faire les choses, car les objets peuvent être variables, le vôtre peut fonctionner si vous parlez d'objet statique tout au long du cycle de vie de l'application, mais parfois nous avons besoin d'objets passionnants qui peuvent être générés à l'aide de webservice ou ainsi stackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri
Je l'ai utilisé avec succès avec des objets générés à partir de services Web en ayant une portée d'application Mapoù les objets sont stockés et récupérés à l'aide d'un identifiant. Le seul vrai problème avec cette approche est qu'Android efface la mémoire après un certain temps, vous devez donc vérifier les valeurs nulles sur votre onResume (je pense que les objets passés en intention sont persistants mais je ne suis pas sûr). En dehors de cela, je ne vois pas cela comme étant nettement inférieur.
Saad Farooq
C'est la meilleure réponse. Il montre comment différentes activités peuvent référencer le même modèle de données. Il m'a fallu beaucoup trop de temps pour découvrir cela!
Markus
6

dans votre modèle de classe (Object) implémentez Serializable, par exemple:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

et votre première activité

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

et votre deuxième activité (NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

bonne chance!!

David Hackro
la source
6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

Transmission des données:

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

Récupération des données:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");
Adnan Abdollah Zaki
la source
5

la solution la plus simple que j'ai trouvée est .. de créer une classe avec des membres de données statiques avec des setters getters.

définir à partir d'une activité et obtenir d'une autre activité cet objet.

activité A

mytestclass.staticfunctionSet("","",""..etc.);

activité b

mytestclass obj= mytestclass.staticfunctionGet();
UMAR
la source
1
ou créez une classe sérialisable pour passer à une autre activité tout ce que vous voulez passer.
UMAR
9
N'oubliez pas de ne pas mettre de gros objets gras. La durée de vie de cet objet sera la même que la durée de vie de l'application. Et ne stockez jamais de vues. Cette méthode garantit également les fuites de mémoire.
Reno
1
Cette réponse est utile mais pas une meilleure solution en termes d'optimisation de la mémoire et des ressources
Atul Bhardwaj
1
Cela rompt les principes de la POO en introduisant des variables globales. Vous ne savez jamais, dans quel état ils sont, qu'ils soient définis ou non, ils sont utilisés par de nombreux threads et vous devez faire face à cette complexité. C'est généralement une bonne fuite de mémoire, car vous ne savez même pas quand libérer ces variables. Pour ne pas dire qu'il introduit un couplage direct dur entre les différents modules de l'application.
afrish
2
WTF? Les deux autres réponses sont bien supérieures.
IcyFlame
4

vous pouvez utiliser les méthodes putExtra (Serializable ..) et getSerializableExtra () pour passer et récupérer des objets de votre type de classe; vous devrez marquer votre classe Serializable et vous assurer que toutes vos variables membres sont également sérialisables ...

nul
la source
4

Créer une application Android

Fichier >> Nouveau >> Application Android

Entrez le nom du projet: android-pass-object-to-activity

Pakcage: com.hmkcode.android

Gardez d'autres sélections par défaut, allez ensuite jusqu'à ce que vous atteigniez Terminer

Avant de commencer à créer l'application, nous devons créer la classe POJO «Person» que nous utiliserons pour envoyer un objet d'une activité à une autre. Notez que la classe implémente l'interface Serializable.

Person.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

Deux dispositions pour deux activités

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

Deux classes d'activités

1) ActivityMain.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2) AnotherActivity.java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}
MFP
la source
4

En utilisant la bibliothèque Gson de Google, vous pouvez passer un objet à une autre activité.En fait, nous convertirons l'objet sous la forme d'une chaîne json et après le passage à une autre activité, nous le reconvertirons à nouveau en un objet comme celui-ci

Considérez une classe de haricots comme celle-ci

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

Nous devons passer l'objet de la classe Example

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

Pour la lecture, nous devons faire l'opération inverse dans NextActivity

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

Ajouter cette dépendance en gradle

compile 'com.google.code.gson:gson:2.6.2'
Jinesh Francis
la source
3
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);
Manas Ranjan
la source
3

Je sais que c'est tard mais c'est très simple. Tout ce que vous avez à faire est de laisser votre classe implémenter Serializable comme

public class MyClass implements Serializable{

}

alors vous pouvez passer à une intention comme

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

Pour l'obtenir, vous appelez simplement

MyClass objec=(MyClass)intent.getExtra("theString");
suulisine
la source
2

Si vous avez de toute façon une classe singleton (service fx) servant de passerelle vers votre couche modèle, elle peut être résolue en ayant une variable dans cette classe avec des getters et des setters pour elle.

Dans l'activité 1:

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

Dans l'activité 2:

private Service service;
private Order order;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quality);

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

En service:

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

Cette solution ne nécessite aucune sérialisation ou autre "packaging" de l'objet en question. Mais cela ne sera bénéfique que si vous utilisez ce type d'architecture de toute façon.

Kitalda
la source
Quels sont les inconvénients de cette approche? Cela semble si logique et mince. J'ai toujours lu que vous ne devriez pas faire ça, mais je n'ai jamais une bonne explication sur ce qui pourrait mal tourner.
Markus
Puisque je ne peux plus éditer mon commentaire: N'est-ce pas la seule solution possible pour obtenir une référence à un objet au lieu d'une copie? J'ai besoin de récupérer le même objet et non une copie!
Markus
Je pense que cela est quelque peu découragé en raison du couplage élevé qu'il entraîne. Mais oui, pour autant que je puisse voir, cette approche est la plus viable si vous avez besoin de l'objet réel. Comme toujours en programmation, vous pouvez faire ce que vous voulez, vous voulez juste le faire avec soin. Cette solution a fonctionné pour moi, et je la préfère car j'utilise de toute façon cette architecture.
Kitalda
En fait, j'ai fini par étendre la classe Application et y ai stocké mon modèle de données. Dans les intentions, j'ai uniquement relayé l'ID des objets de données qui pouvaient être utilisés pour récupérer l'objet d'origine de la classe Application. De plus, la classe d'application étendue notifie tous les objets qui utilisent le modèle de données s'il change via un concept d'écouteur standard. Je sais que cela ne convient qu'à mon cas où j'ai besoin de partager un modèle de données sur toute l'application, mais pour ce cas, ses classes et champs statiques parfaits et nécessaires également!
Markus
2

De loin le moyen le plus simple à mon humble avis de coliser des objets. Vous venez d'ajouter une balise d'annotation au-dessus de l'objet que vous souhaitez rendre parcellaire.

Un exemple de la bibliothèque est ci-dessous https://github.com/johncarl81/parceler

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

    public Example(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() { return name; }

    public int getAge() { return age; }
}
Ryan
la source
2

Implémentez d' abord Parcelable dans votre classe. Passez ensuite un objet comme celui-ci.

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

La chaîne de package n'est pas nécessaire, juste la chaîne doit être la même dans les deux activités

RÉFÉRENCE

Arpit Patel
la source
2

Démarrer une autre activité à partir de ces paramètres de passe d'activité via l'objet Bundle

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "[email protected]");
startActivity(intent);

Récupérer sur une autre activité (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

C'est ok pour un type de données simple. Mais si vous voulez transmettre des données complexes entre deux activités, vous devez d'abord les sérialiser.

Ici, nous avons le modèle des employés

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Vous pouvez utiliser la bibliothèque Gson fournie par Google pour sérialiser les données complexes comme celle-ci

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
    String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);
1101821
la source
2

À Koltin

Ajoutez l'extension kotlin dans votre build.gradle.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

Créez ensuite votre classe de données comme ceci.

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

Passer un objet avec intention

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

Obtenir un objet avec intention

val sample = intent.getParcelableExtra("id")
Naveen
la source
Est-ce encore expérimental?
ShadeToD
2

La manière la plus simple et java de faire est: implémenter sérialisable dans votre classe pojo / modèle

Recommandé pour Android pour l'affichage des performances: rendre le modèle parcellable

Ashok Kumar
la source
1

Le plus simple serait d'utiliser simplement ce qui suit lorsque l'élément est une chaîne:

intent.putextra("selected_item",item)

Pour recevoir:

String name = data.getStringExtra("selected_item");
ankish
la source
3
son pour chaîne, entier et etc uniquement, mais je veux que l'objet et en utilisant un objet statique son seul possible.
UMAR