Comment passer d'un objet à partir d'une activité à l'autre sur Android
Je suis en train de travailler sur l'envoi d'un objet de mon client classe à partir d'un Activity
et l'afficher dans une autre Activity
.
Le code de la classe de la clientèle:
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 à partir d'un Activity
à l'autre et afficher les données sur les autres Activity
.
Comment puis-je y parvenir?
- probablement, vous devez modifier la accepté de réponse au vu de la masse de l'opinion.
- J'ai utilisé pour définir l'objet de Pacelable ou Serializable, mais à chaque fois que j'ajoute d'autres variables, je dois ajouter toutes les fonctions get et set pour Pacelable ou Serializable. j'ai donc fait DataCache de transfert entre les activités et les fragments. github.com/kimkevin/AndroidDataCache C'est super facile pour objet de transfert.
Vous devez vous connecter pour publier un commentaire.
Une option pourrait être de laisser votre classe personnalisée de mettre en œuvre la
Serializable
interface et ensuite vous pouvez passer des instances de l'objet dans l'intention supplémentaire à l'aide de laputExtra(Serializable..)
variante de laIntent#putExtra()
méthode.Pseudocode:
Remarque: assurez-vous que chaque classe imbriquée de votre classe principale personnalisé a mis en œuvre l'interface Serializable pour éviter toute sérialisation des exceptions. Par exemple:
Parcelable
EST spécialement conçu à cet effet (et beaucoup plus rapide queSerializable
). Je suis confus.Parcelable
peut-être bon pour la vitesse, mais il est compliqué à mettre en œuvre. Que faire si vous avez 8 objets que vous devez passer entre les activités, allez-vous faire de chacunParcelable
? Il serait plus judicieux d'utiliserSerializable
à la place. Lorsque vous implémentezParcelable
vous devez ajouter une grande quantité de code de la classe, et l'ordre des champs dans une manière très spécifique;Serializable
vous n'avez pas. En fin de compte, je pense que ça vient de la façon dont beaucoup d'objets que vous êtes de passage et que vous essayez de faire.Serializable
est une interface Java standard. Il vous suffit de marquer une classe Sérialisable par implenting l'interface, et Java automatiquement sérialiser dans certaines situations.Parcelable
est un Android interface spécifique où vous mettez en œuvre la sérialisation vous-même. Il a été créé pour être beaucoup plus efficace que Serializable, et de contourner certains problèmes avec Java par défaut de sérialisation régimeMettre en œuvre votre classe Sérialisable. Supposons que c'est votre classe d'entité:
Nous sommes l'envoi de l'objet appelé
dene
de X de l'activité pour Y activité. Quelque part dans X de l'activité;En Y de l'activité de l'objet.
Que c'est.
classCastException: java.lang.Long
en le faisant. Pouvez-vous expliquer pourquoi?(Serializable)
à l'objet?Vous pouvez générer Parcelable le code de la classe à l'aide de cette site.
Parcelable
alors, je préfère garder mes classes POJO Android-agnostique et l'utilisationSerializable
.Tout en appelant à une activité
Dans toClass.java recevez l'activité par
Assurez-vous que la clientèle de la classe implémente parcelable
Dans mon expérience, il existe trois solutions principales, chacune avec leurs avantages et des inconvénients:
La Mise En Œuvre De Parcelable
D'Exécution Sérialisable
À l'aide d'une lumière-poids de l'événement de bus de la bibliothèque, de la sorte (par exemple, Greenrobot de l'EventBus ou Square Otto)
Parcelable - rapide et Android standard, mais il a beaucoup de code réutilisable et nécessite des chaînes codées en dur pour référence lors de l'extraction de valeurs de l'objet (non-fortement typé).
Serializable - proche de zéro passe-partout, mais il est le plus lent approche et exige également des chaînes codées en dur quand on tire les valeurs de l'objet (non-fortement typé).
Bus D'Événement - zéro passe-partout, approche plus rapide, et ne nécessite pas de chaînes codées en dur, mais il exige un supplément de dépendance (bien que généralement léger, ~40 KO)
J'ai réalisé une comparaison détaillée autour de ces trois approches, y compris l'efficacité des repères.
Utilisation gson pour convertir votre objet en JSON et le passer à travers intention. Dans la nouvelle Activité de convertir au format JSON à un objet.
Dans votre
build.gradle
, ajouter à vos dépendancesDans votre Activité, de convertir l'objet en json-chaîne:
À réception de votre Activité, de les convertir au format json-chaîne à l'objet d'origine:
Pour Kotlin c'est tout à fait le même
Transmettre les données
Recevoir les données
Gson
--> ici stackoverflow.com/questions/39535222/problems-with-gson-librarypojo
àjson
tout en gardant le représentant de la classe la plus simple possible.Vous pouvez également écrire les données de l'objet temporaire des Chaînes et des services de renseignements, et les passer à l'activité. Bien sûr, de cette façon, vous obtenez les données transportées, mais pas de l'objet lui-même.
Mais si vous voulez juste pour les afficher, et de ne pas utiliser l'objet dans une autre méthode ou quelque chose comme ça, il devrait être suffisant. J'ai fait de la même façon à afficher uniquement les données d'un objet dans une autre activité.
Vous pouvez également les transmettre directement au lieu de la temp ivars, mais de cette façon c'est plus clair, à mon avis. En outre, vous pouvez définir le temp ivars null, afin qu'ils nettoyés par le GarbageCollector plus tôt.
Bonne chance!
Sur une note de côté: remplacer toString() au lieu d'écrire votre propre méthode d'impression.
Comme mentionné dans les commentaires ci-dessous, c'est une façon de récupérer vos données dans une autre activité:
Bundle extras = getIntent().getExtras();
String val = extras.getString("fname");
J'ai trouvé un simple & élégant méthode:
Méthode 1
Code pour la première activité:
De Code pour la deuxième activité:
vous trouverez
objSent
&objReceived
ont la mêmehashCode
, de sorte qu'ils sont identiques.Mais pourquoi ne pouvons-nous passer d'un objet java de cette façon?
En fait, android classeur de créer de la JNI mondiale de référence pour java objet et de le libérer de ce mondial JNI de référence quand il n'y a pas de référence pour cet objet java. classeur de sauver ce JNI mondiale de référence dans l'objet de Classeur.
*ATTENTION: cette méthode ne fonctionne que si les deux activités exécutées dans le même processus, autrement jeter ClassCastException au (ObjectWrapperForBinder)getIntent().getExtras().getBinder("object_value") *
classe ObjectWrapperForBinder defination de
Méthode 2
JNIEnv::DeleteGlobalRef),
Mais la Méthode 2 a un peu, mais sérieux, si le récepteur ne parviennent pas à rétablir l'objet java (par exemple, une exception se produire avant la restauration de l'objet java, ou le récepteur de l'Activité, il n'existe pas), puis de l'objet java deviendra un orphelin ou de fuite de mémoire,
Méthode 1 n'ont pas ce problème, parce qu'android classeur de gérer cette exception
Méthode 3
D'invoquer l'objet java à distance, nous allons créer un contrat de données/interface pour décrire l'objet java, nous allons utiliser l'aidl fichier
IDataContract.aidl
Code pour la première activité
De Code pour la deuxième activité:
changer le android:processus d'attribut dans AndroidManifest.xml pour un non-vide nom du processus pour s'assurer que la deuxième activité de l'exécuter dans un autre processus
De cette façon, nous pouvons passer d'une interface entre deux activités, même si ils courent dans les différents processus, et d'appeler la méthode de l'interface à distance
Méthode 4
méthode 3 ne semblent pas assez simple parce que nous devons mettre en œuvre une aidl interface.
Si vous voulez juste faire une tâche simple et la méthode de la valeur de retour est inutile, on peut utiliser android.os.Messenger
Code pour la première activité( expéditeur):
De Code pour la deuxième activité ( récepteur ):
Tous le Messager.envoyez s'exécuter dans un Gestionnaire de façon asynchrone, et de manière séquentielle.
En fait, android.os.Messenger est un aidl de l'interface, si vous avez le code source android, vous pouvez trouver un fichier nommé IMessenger.aidl
J'ai fait un singleton helper classe qui contient les objets temporaires.
Au lieu de mettre vos objets à l'intérieur de l'Intention, de l'utilisation IntentHelper:
À l'intérieur de votre nouvelle Activité, vous pouvez obtenir l'objet:
Garder à l'esprit qu'une fois chargé, l'objet est supprimé pour éviter les références inutiles.
BookActivity.getInstance().recommendationResponse
dansRoomsActivity
obj
devientnull
. Pour éviter cela,obj
doivent être stockés quelque part pour l'obtenir à nouveau. En effet, le Json solution stocke les données de l'objet dans l'Intention.Il ya un couple de façons dont vous pouvez accéder à des variables ou des objets dans d'autres classes ou de l'Activité.
A. Base De Données
B. Partagé préférences.
C. sérialisation d'un Objet.
D. Une classe qui peut contenir des données communes peuvent être désignés comme des Utilitaires Communs. Il dépend de vous.
E. la transmission des données par le biais d'Intentions et de l'Interface Parcelable.
Il dépend des besoins de votre projet.
A. Base De Données
SQLite est une base de données open source qui est intégré dans Android. SQLite prend en charge la norme de base de données relationnelle fonctionnalités comme la syntaxe SQL, des opérations et déclarations préparées à l'avance.
Tutoriels
B. Partagé préférences
Supposons que vous souhaitez stocker le nom d'utilisateur. Donc, il y a maintenant de deux choses l'une, un clé nom d'utilisateur, valeur valeur.
Comment stocker
À l'aide de putString(), putBoolean(), putInt(), putFloat(), et putLong (), vous pouvez enregistrer votre choix dtatype.
Comment extraire les
http://developer.android.com/reference/android/content/SharedPreferences.html
C. sérialisation d'un Objet
Objet serlization est utilisé si l'on veux enregistrer un état de l'objet à envoyer sur un réseau ou vous pouvez l'utiliser pour votre usage aussi.
Utiliser Java beans et de les stocker dans un de ses champs et de l'utilisation des getters et setter pour que.
JavaBeans sont des classes Java qui ont des propriétés. Pensez
propriétés privées variables d'instance. Depuis qu'ils sont privés, la seule façon
ils peuvent être accessibles à partir de l'extérieur de leur classe par le biais de méthodes dans la classe. Les méthodes de modifier une valeur de la propriété sont appelées des méthodes de définition, et les méthodes permettant d'extraire une valeur de la propriété sont appelées des méthodes de lecture.
Définir la variable dans votre mail, en utilisant la méthode
Puis utiliser l'objet serialzation de sérialiser et dans d'autres classe désérialiser cet objet.
Dans la sérialisation d'un objet peut être représenté comme une séquence d'octets qui comprend 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.
Après un objet sérialisé a été écrit dans un fichier, il peut être lu à partir du fichier et désérialisé. C'est le type d'information et d'octets qui représentent l'objet et ses données peuvent être utilisées pour recréer l'objet en mémoire.
Si vous voulez un tutoriel pour cela se référer à:
La sérialisation en Java (blog)
Obtenez variable dans d'autres classes (Débordement De Pile)
D. CommonUtilities
Vous pouvez faire une classe par vous-même qui peut contenir les données qui vous avez souvent besoin dans votre projet.
Échantillon
E. la transmission des données à travers les intentions de
Veuillez consulter le tutoriel Android – Parcelle de données à transmettre entre les Activités à l'aide de Parcelable classes pour cette option de transmission de données.
Créer votre propre classe
Customer
comme suit:Dans votre
onCreate()
méthodeDans
xyz activity
classe, vous devez utiliser le code suivant:Le meilleur moyen est d'avoir une classe (appelons-le Contrôle) dans votre application qui va contenir une variable statique de type "Client" (dans votre cas). Initialiser la variable dans votre Activité A.
Par exemple:
Ensuite, allez à l'Activité de B et récupérer à partir de la classe de Contrôle. N'oubliez pas d'attribuer une valeur nulle après l'utilisation de la variable, sinon, de mémoire, sera gaspillé.
Maintenant, vous voulez passer de l'objet de cette classe dans startActivity. Utilisez simplement ceci:
Cela fonctionne ici, car Maclasse implements
Serializable
.Si vous choisissez d'utiliser la voie Samuh décrit, n'oubliez pas que seules les valeurs primitives peuvent être envoyés. Cela signifie que les valeurs qui sont parcable. Donc, si votre objet contient des objets complexes elles ne pourront pas suivre. Par exemple, des variables comme Bitmap, HashMap, etc... sont difficiles à passer par l'intention.
En général, je vous conseillerais de vous envoyer seulement les types de données primitifs que les extras, comme String, int, boolean, etc. Dans votre cas, il serait:
String fname
,String lname
,int age
, etString address
.Mon avis: des objets Plus complexes sont mieux partagés par la mise en œuvre d'un ContentProvider, SDCard, etc. Il est également possible d'utiliser un variable statique, mais cela peut rapidement conduire à des erreurs de code...
Mais encore une fois, c'est juste mon opinion subjective.
Je suis en utilisant parcelable pour envoyer des données à partir d'une activité à une autre acivity. Voici mon code qui fonctionne très bien dans mon projet.
Dans activityA l'utiliser comme ceci:
Dans ActivityB l'utiliser comme ceci pour obtenir des données:
Vous pouvez essayer d'utiliser cette classe. La limitation est qu'il ne peut pas être utilisé en dehors d'un processus.
Une activité:
Autre activité:
Démarrer une autre activité de cette activité et de passer des paramètres via le Faisceau Objet
Restauration de données sur une autre activité (YourActivity)
C'est ok pour de simples genre de type de données.
Mais si tu veux passer des données complexes entre l'activité. U besoin de sérialiser en premier.
Ici, nous avons Employé Modèle
Vous pouvez utiliser Gson lib fourni par google pour sérialiser les données complexes
comme ce
Cette question est également abordée dans un autre Débordement de Pile question. Jetez un oeil à une solution à la transmission des données par le biais de l'intention à l'aide de Serializable. Le point principal est sur l'utilisation de
Bundle
objet qui stocke les données nécessaires à l'intérieur deIntent
.Pour extraire des valeurs:
Avantage de
Serializable
est sa simplicité. Toutefois, vous devriez envisager d'utiliserParcelable
méthode si vous avez besoin de beaucoup de données à transférer, parce queParcelable
est spécialement conçu pour Android et il est plus efficace queSerializable
. Vous pouvez créerParcelable
classe à l'aide de:Crète une classe comme la classe d'haricot et de mettre en œuvre la
Serializable
interface. Ensuite, nous pouvons passer à travers laintent
méthode, par exemple:Puis l'obtenir à partir de l'autre activité, par exemple:
Créer deux méthodes dans votre Classe personnalisée comme ce
Maintenant dans votre expéditeur de l'Activité de faire comme ceci
Et dans votre Activité récepteur
Ouais, à l'aide d'un objet statique est de loin la façon la plus simple de le faire avec la coutume non-serialisable objets.
static
est la meilleure solution de contournement si c'est tout simplement impossible de garder en invoquantputExtra()
pour chaque propriété que vous souhaitez transmettre. Par exemple, maintenant, je veux passer unArrayList
qui contient des objets. Je pourrais tout aussi bien faire mon ArrayListstatic
à la place.Android Activité les objets peuvent être détruits et reconstitué. Ainsi, vous aurez besoin d'utiliser une autre approche pour rechercher - ou n'importe quel objet ils créent!!! - jusqu'. Qui est, vous pourriez passer comme statique de la classe de référence, mais alors le handle d'objet (Java appelle ces "références", comme SmallTalk; mais ils ne sont pas des références dans le sens de C ou de l'assemblée) sera peut-être pas valide tard, car il est une "fonctionnalité" de Android OE est toute Activité peut être anéanti et reconstitué plus tard.
L'original de la question posée "Comment passer de l'objet à partir d'une activité à l'autre dans Android" et personne n'a répondu. Pour sûr, vous pouvez sérialisé (Serializable, Parcelable, depuis JSON) et de transmettre une copie des données de l'objet et un nouvel objet ayant les mêmes données pourraient être créés; mais il n'aura PAS les mêmes références/poignées. Aussi, beaucoup d'autres l'ont mentionné, vous pouvez stocker la référence statique le magasin. Et qui va travailler à moins d'Android décide de onDestroy de votre Activité.
Donc, pour vraiment résoudre la question d'origine vous avez besoin d'une statique de recherche de plus chaque objet de mise à jour de sa référence quand/si elle est recréée. E. g. chaque Android Activité est susceptible de remettre en vente lui-même si ses onCreate est appelé. Vous pouvez également voir comment certaines personnes utilisent la liste des tâches à la recherche d'une Activité en nom. (le système est temporairement en train de détruire cette instance de l'activité pour économiser de l'espace..getRunningTasks, la liste des tâches est effectivement spécialisé de la liste de la plus récente de l'objet instance de chaque Activité).
Pour référence:
Donc, le Bus de Message est une solution viable. Il fondamentalement des "plates". Plutôt que d'essayer d'avoir des références à des objets; puis vous re-architecte de votre conception à l'utilisation MessagePassing au lieu de SequentialCode. Exponentiellement plus difficile à déboguer; mais elle permet d'ignorer ces sortes de OperatingEnvironment de compréhensions. Effectivement, chaque objet de la méthode d'accès est inversé de sorte que l'appelant envoie un Message et l'objet lui-même définit un gestionnaire pour ce message. Beaucoup plus de code, mais peut le rendre robuste avec de l'Android OE restrictions.
Si tout ce que vous voulez, c'est le top de l'Activité (chose typique dans les applications Android à cause du "Contexte" d'être partout), alors vous pouvez juste avoir à chaque Activité listes de lui-même comme "top" de la statique global de l'espace à chaque fois que son onResume est appelé. Ensuite, votre AlertDialog ou tout ce qui a besoin d'un contexte suffit de prendre à partir de là. Aussi, il est un peu dégoûtant à utiliser une approche globale, mais peut simplifier le passage d'un Cadre en haut et en bas, partout, et, bien sûr, lorsque vous utilisez un MessageBus puis IL EST global, de toute façon.
Je sais que statique est mauvais, mais il me semble que nous sommes obligés de l'utiliser ici. Le problème avec parceables/seriazables est que les deux activités sont en double instances du même objet = déchets de mémoire et de CPU.
Appelant activité
Appelé activité (à noter que onCreate() et onResume() peut être appelé plusieurs fois lorsque le système détruit et recrée des activités)
Une autre solution est de déclarer un champ statique de la classe que vous souhaitez passer dans la classe. Il servira uniquement à cette fin. N'oubliez pas qu'il peut être null dans onCreate, parce que votre package d'application a été déchargé de la mémoire par le système et la recharger plus tard.
En gardant à l'esprit que vous devez toujours gérer l'activité du cycle de vie, vous pouvez écrire toutes les données directement à un partage de préférences, douloureuses, avec des structures de données complexes comme il est.
Réponses ci-dessus, presque tous les corriger, mais pour ceux qui n'ont pas de comprendre ces réponses
Android a puissant de la classe Intention avec l'aide de vous partager des données entre non seulement l'activité mais d'un autre des composants d'Android (broadcasr récepteur, services internes connexes pour fournir du contenu, nous utilisons ContetnResolver classe pas l'Intention).
Dans votre activité, vous construire intention
Dans receving votre activité, vous avez
Vous avez à mettre en œuvre Parceable ou l'interface Serializable sur votre objet afin de le partager entre les activités. Il est difficile de mettre en œuvre Parcealbe plutôt que Serializable interface de l'objet c'est pourquoi android a plugin spécialement pour cela.Télécharger et de l'utiliser
Je me suis toujours demandé pourquoi cela ne peut pas être aussi simple que d'appeler une méthode de l'autre activité. J'ai récemment écrit un utilitaire de la bibliothèque qui le rend presque aussi simple que ça. Vous pouvez le vérifier ici(https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher).
GNLauncher fait de l'envoi d'objets de données pour une Activité à partir d'une autre Activité, etc aussi simple que d'appeler une fonction dans tha Activité avec les données requises en tant que paramètres. Il introduit le type de sécurité et supprime toutes les hastles d'avoir à sérialiser, en joignant à l'intention à l'aide de clés de chaîne et défaire le même à l'autre bout.
Utilisation
Définir une interface avec les méthodes que vous voulez l'appeler sur l'Activité de lancement.
Mettre en œuvre l'interface ci-dessus sur l'Activité pour se lancer dans l'.
Aussi en informer GNLauncher lorsque l'activité est prêt.
Dans l'autre Activité, obtenir un proxy à l'Activité ci-dessus et appeler n'importe quelle méthode avec les paramètres souhaités.
La première activité sera lancée et la méthode appelée avec les paramètres requis.
Conditions préalables
Veuillez vous référer à https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites pour plus d'informations sur la façon d'ajouter les dépendances.
Pass objet d'une activité à une autre activité.
(1) source de l'activité
(2) destination acitivité
J'ai utilisé pour définir l'objet avec Pacelable ou Serializable de transfert, mais à chaque fois que j'ajoute d'autres variables de l'objet(modèle), je l'enregistrer tous. C'est tellement nconvenient.
C'est super facile le transfert d'objet entre les activités ou les fragments.
Android DataCache
Nous pouvons passer de l'objet à partir d'une activité à une autre activité:
À l'intérieur de
poSuppliersDetails
nous avons certaines valeurs. Maintenant, je suis l'envoi de cet objet pour l'activité cible:Comment obtenir ce ACtivityTwo:
Passer d'une activité à l'autre:
Obtenir les valeurs:
Bonjour à tous, je vois beaucoup de bonnes options, mais je me demandais pourquoi la Liaison n'a pas été utilisé?
La création d'un Classeur est assez simple...
Et de la création de la parcelable pour l'utiliser, il n'est pas mauvais de l'éther.
Cette logique, c'est vraiment cool, parce que vous êtes réellement en passant une référence d'activité.
et de mettre en œuvre ce que vous venez de...
Envoyer
Récupérer
Diable quelqu'un pourrait obtenez tous fous et en faire ce con un vrai générique.
Comme mentionné dans les commentaires, cette réponse pauses encapsulation et étroitement les couples composants, ce qui est très probablement pas ce que vous voulez. La meilleure solution est probablement de faire votre objet Parcelable ou Serializable, comme d'autres réponses expliquer. Cela dit, la solution permet de résoudre le problème. Donc, si vous savez ce que vous faites:
Utiliser une classe avec des champs statiques:
À l'intérieur les activités que vous pouvez utiliser:
Activité À Partir De:
Activité Cible:
C'est un moyen facile de passer de l'information pour les activités.