J'ai une activité qui est la principale activité utilisée dans l'application et qui comporte un certain nombre de variables. J'ai deux autres activités que j'aimerais pouvoir utiliser les données de la première activité. Maintenant je sais que je peux faire quelque chose comme ça:
GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();
Cependant, je veux partager beaucoup de variables et certaines peuvent être plutôt grandes, donc je ne veux pas en créer des copies comme ci-dessus.
Existe-t-il un moyen d'obtenir et de modifier directement les variables sans utiliser les méthodes get et set? Je me souviens avoir lu un article sur le site de développement Google disant que ce n'est pas recommandé pour les performances sur Android.
Réponses:
Voici une compilation des moyens les plus courants pour y parvenir :
WeakReferences
TL; DR : il existe deux façons de partager des données: passer des données dans les extras de l'intention ou les enregistrer ailleurs. Si les données sont des primitives, des chaînes ou des objets définis par l'utilisateur: envoyez-les dans le cadre des extras d'intention (les objets définis par l'utilisateur doivent implémenter
Parcelable
). Si vous passez des objets complexes, enregistrez une instance dans un singleton ailleurs et accédez-y à partir de l'activité lancée.Quelques exemples de comment et pourquoi mettre en œuvre chaque approche:
Envoyer des données dans des intentions
Sur la deuxième activité:
Utilisez cette méthode si vous transmettez des données primitives ou des chaînes . Vous pouvez également passer des objets qui implémentent
Serializable
.Bien que tentant, vous devriez réfléchir à deux fois avant de l'utiliser
Serializable
: il est sujet aux erreurs et horriblement lent. Donc en général: éloignez-vousSerializable
si possible. Si vous souhaitez transmettre des objets définis par l'utilisateur complexes, jetez un œil à l'Parcelable
interface . Il est plus difficile à mettre en œuvre, mais il a des gains de vitesse considérables par rapport àSerializable
.Partagez des données sans persister sur le disque
Il est possible de partager des données entre des activités en les enregistrant en mémoire étant donné que, dans la plupart des cas, les deux activités s'exécutent dans le même processus.
Remarque: parfois, lorsque l'utilisateur quitte votre activité (sans la quitter), Android peut décider de tuer votre application. Dans un tel scénario, j'ai rencontré des cas dans lesquels Android tente de lancer la dernière activité en utilisant l'intention fournie avant la mort de l'application. Dans ce cas, les données stockées dans un singleton (le vôtre ou
Application
) disparaîtront et de mauvaises choses pourraient se produire. Pour éviter de tels cas, vous pouvez soit persister les objets sur le disque, soit vérifier les données avant de les utiliser pour vous assurer qu'elles sont valides.Utiliser une classe singleton
Demandez à une classe de conserver les données:
De l'activité lancée:
Utiliser l'application singleton
Le singleton d'application est une instance
android.app.Application
qui est créée lorsque l'application est lancée. Vous pouvez en fournir un personnalisé en étendantApplication
:Avant de lancer l'activité:
Ensuite, à partir de l'activité lancée:
Champs statiques
L'idée est fondamentalement la même que celle du singleton, mais dans ce cas, vous fournissez un accès statique aux données:
De l'activité lancée:
HashMap of
WeakReferences
Même idée, mais en permettant au garbage collector de supprimer les objets non référencés (par exemple lorsque l'utilisateur quitte l'activité):
Avant de lancer l'activité:
De l'activité lancée:
Vous devrez peut-être ou non passer l'ID d'objet à l'aide des extras de l'intention. Tout dépend de votre problème spécifique.
Persister les objets sur le disque
L'idée est de sauvegarder les données sur disque avant de lancer l'autre activité.
Avantages: vous pouvez lancer l'activité à partir d'autres endroits et, si les données sont déjà persistantes, cela devrait fonctionner correctement.
Inconvénients: il est lourd et prend plus de temps à mettre en œuvre. Nécessite plus de code et donc plus de chances d'introduire des bogues. Ce sera également beaucoup plus lent.
Certaines des façons de conserver les objets incluent:
la source
setResult
méthode. De plus, dans ce cas, l'activité secondaire doit être appelée à l'aide de lastartActivityForResult
méthode.Activity
partout, et dans saonCreate()
vérification tout champ statique du singleton que vous remplissez lors du démarrage de l'application. Si ce champ est vide, revenez à l'activité de démarrage à l'aide deFLAG_ACTIVITY_CLEAR_TASK
ou deBroadcastReceiver
pour supprimer d'autres activités.Ce que vous pouvez utiliser:
Ce que vous choisissez dépend de vos besoins. Vous utiliserez probablement plus d'une façon lorsque vous avez "beaucoup de"
la source
MAIN
action. Après la mort du processus, vous redémarrez sur toute activité ouverte en dernier, ce qui pourrait être une page de détails quelque part au fond de l'application.Faites ce que Google vous commande de faire! ici: http://developer.android.com/resources/faq/framework.html#3
la source
Cela ne fait pas de copie (en particulier avec String , mais même les objets passent par la valeur de la référence, pas l'objet lui-même, et les getter comme ça sont bien à utiliser - sans doute mieux à utiliser que d'autres moyens car ils sont communs et bien compris). Les anciens «mythes sur les performances», comme le fait de ne pas utiliser les getters et les setters, ont toujours une certaine valeur, mais ont également été mis à jour dans les documents .
Mais si vous ne voulez pas faire cela, vous pouvez également simplement rendre les variables publiques ou protégées dans GlobalState et y accéder directement. Et, vous pouvez créer un singleton statique comme l' indique l'objet Application JavaDoc :
L'utilisation des données d' intention , comme le notent d'autres réponses ici, est un autre moyen de transmettre des données, mais il est généralement utilisé pour des données plus petites et des types simples. Vous pouvez transmettre des données plus grandes / plus complexes, mais c'est plus compliqué que de simplement utiliser un singleon statique. L' objet Application est toujours mon préféré pour partager des données non persistantes plus grandes / plus complexes entre les composants d'application Android (car il a un cycle de vie bien défini dans une application Android).
En outre, comme d'autres l'ont noté, si les données deviennent très complexes et doivent être persistantes, vous pouvez également utiliser SQLite ou le système de fichiers.
la source
Vous pouvez étendre la classe Application et la balise sur tous les objets que vous souhaitez, ils sont ensuite disponibles n'importe où dans votre application
la source
Il existe une nouvelle et meilleure façon de partager des données entre les activités, et c'est LiveData . Notez en particulier cette citation de la page du développeur Android:
L'implication de ceci est énorme - toutes les données de modèle peuvent être partagées dans une classe singleton commune à l'intérieur d'un
LiveData
wrapper. Il peut être injecté des activités dans leurs domaines respectifsViewModel
par souci de testabilité. Et vous n'avez plus à vous soucier des références faibles pour éviter les fuites de mémoire.la source
L'utilisation de la table de hachage de l'approche de référence faible, décrite ci-dessus, et dans http://developer.android.com/guide/faq/framework.html me semble problématique. Comment les entrées entières sont-elles récupérées, pas seulement la valeur de la carte? Dans quelle portée l'allouez-vous? Comme le cadre contrôle le cycle de vie de l'activité, le fait de posséder l'une des activités participantes risque de provoquer des erreurs d'exécution lorsque le propriétaire est détruit avant ses clients. Si l'application en est propriétaire, une activité doit supprimer explicitement l'entrée pour éviter que la table de hachage ne conserve les entrées avec une clé valide et une référence faible collectée potentiellement endommagée. De plus, que doit faire un client lorsque la valeur renvoyée pour une clé est nulle?
Il me semble qu'un WeakHashMap appartenant à l'application ou au sein d'un singleton est un meilleur choix. Une valeur dans la carte est accessible via un objet clé, et lorsqu'il n'existe aucune référence forte à la clé (c'est-à-dire que toutes les activités sont effectuées avec la clé et ce à quoi elle est mappée), GC peut récupérer l'entrée de la carte.
la source
Il existe différentes façons de partager des données entre les activités
1: Transmission de données entre les activités à l'aide d'Intention
2: En utilisant un mot-clé statique, définissez la variable comme statique publique et utilisez n'importe où dans le projet
utiliser n'importe où dans le projet en utilisant classname.variableName;
3: Utilisation de la base de données
mais son processus est un peu long, vous devez utiliser une requête pour insérer des données et itérer les données en utilisant le curseur en cas de besoin. Mais il n'y a aucune chance de perdre des données sans nettoyer le cache.
4: Utilisation des préférences partagées
beaucoup plus facile que la base de données. mais il y a une limitation, vous ne pouvez pas enregistrer les objets ArrayList, List et custome.
5: Créez un setter getter dans la classe Aplication et accédez à n'importe où dans le projet.
ici mis et obtenir des activités
la source
Eh bien, j'ai quelques idées, mais je ne sais pas si elles sont ce que vous cherchez.
Vous pouvez utiliser un service contenant toutes les données, puis lier simplement vos activités au service pour la récupération des données.
Ou regroupez vos données dans un fichier sérialisable ou parcellable et attachez-les à un bundle et passez le bundle entre les activités.
Celui-ci n'est peut-être pas du tout ce que vous recherchez, mais vous pouvez également essayer d'utiliser des préférences partagées ou une préférence en général.
Quoi qu'il en soit, faites-moi savoir ce que vous décidez.
la source
En supposant que vous appelez l'activité deux de l'activité un en utilisant une intention.
Vous pouvez transmettre les données avec l'intention.putExtra (),
Prenez ceci pour votre référence. Envoi de tableaux avec Intent.putExtra
J'espère que c'est ce que tu veux.
la source
Si votre intention est d'appeler d'autres activités à partir de l'activité en cours, vous devez utiliser Intents . Votre objectif pourrait être moins de conserver des données que de les partager au besoin.
Cependant, si vous avez vraiment besoin de conserver ces valeurs, vous pouvez les conserver dans une sorte de fichier texte structuré ou de base de données sur le stockage local. Un fichier de propriétés, un fichier XML ou un fichier JSON peut stocker vos données et être facilement analysé lors de la création d'activité. N'oubliez pas également que vous avez SQLite sur tous les appareils Android, vous pouvez donc les stocker dans une table de base de données. Vous pouvez également utiliser une carte pour stocker des paires clé-valeur et sérialiser la carte vers le stockage local, mais cela peut être trop lourd pour être utile pour des structures de données simples.
la source
Toutes les réponses susmentionnées sont excellentes ... J'ajoute juste une que personne n'avait encore mentionnée sur la persistance des données à travers les activités et qui consiste à utiliser la base de données SQLite Android intégrée pour conserver les données pertinentes ... En fait, vous pouvez placer votre databaseHelper dans l'état de l'application et appelez-le selon les besoins tout au long des activations .. Ou créez simplement une classe d'assistance et effectuez les appels de base de données en cas de besoin ... Il suffit d'ajouter une autre couche à prendre en compte ... Mais toutes les autres réponses suffiraient aussi bien. Vraiment juste une préférence
la source
Partage de données entre activités exemple passant un email après la connexion
"email" est le nom qui peut être utilisé pour référencer la valeur de l'activité demandée
1 Code sur la page de connexion
2 code sur la page d'accueil
la source
Et si vous voulez travailler avec un objet de données, ces deux implémentations sont très importantes:
Sérialisable vs Parcelable
public class User implements Parcelable
vérifiez plus ici
la source