Quelle est la meilleure façon de partager des données entre les activités?

J’ai une activité qui est l’activité principale 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(); Ssortingng s = gs.getTestMe(); 

Cependant, je veux partager beaucoup de variables et certaines pourraient être assez volumineuses, alors 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 d’avoir lu un article sur le site de développement de Google indiquant que cela n’était pas recommandé pour les performances sur Android.

Voici une compilation des moyens les plus courants pour y parvenir :

  • Envoyer des données dans l’intention
  • Champs statiques
  • HashMap de WeakReferences
  • Objets persistants (sqlite, préférences de partage, fichier, etc.)

TL; DR : il existe deux manières de partager des données: transmettre 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 objects définis par l’utilisateur: envoyez-les dans le cadre des options supplémentaires (les objects définis par l’utilisateur doivent implémenter Parcelable ). Si vous passez des objects complexes, enregistrez une instance dans un singleton ailleurs et accédez-y depuis l’activité lancée.

Quelques exemples de comment et pourquoi mettre en œuvre chaque approche:

Envoyer des données à l’intérieur des intentions

 Intent intent = new Intent(FirstActivity.this, SecondActivity.class); intent.putExtra("some_key", value); intent.putExtra("some_other_key", "a value"); startActivity(intent); 

Sur la deuxième activité:

 Bundle bundle = getIntent().getExtras(); int value = bundle.getInt("some_key"); Ssortingng value2 = bundle.getSsortingng("some_other_key"); 

Utilisez cette méthode si vous transmettez des données primitives ou des chaînes . Vous pouvez également transmettre des objects qui implémentent Serializable .

Bien que tentant, vous devriez réfléchir à deux fois avant d’utiliser Serializable : c’est sujet aux erreurs et terriblement lent. Donc en général, restz loin de Serializable si possible. Si vous souhaitez transmettre des objects complexes définis par l’utilisateur, consultez l’interface Parcelable . Il est plus difficile à mettre en œuvre, mais les gains de vitesse sont considérables par rapport à Serializable .

Partager 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, car dans la plupart des cas, les deux activités sont exécutées dans le même processus.

Remarque: parfois, lorsque l’utilisateur quitte votre activité (sans le quitter), Android peut décider de tuer votre application. Dans un tel scénario, j’ai rencontré des cas où Android tentait de lancer la dernière activité en utilisant l’intention fournie avant que l’application ne soit supprimée. Dans ce cas, les données stockées dans un singleton (le vôtre ou l’ Application ) disparaîtront et de mauvaises choses risquent de se produire. Pour éviter de tels cas, vous persistez sur le disque ou vérifiez les données avant de l’utiliser pour vous assurer de sa validité.

Utiliser une classe singleton

Avoir une classe pour contenir les données:

 public class DataHolder { private Ssortingng data; public Ssortingng getData() {return data;} public void setData(Ssortingng data) {this.data = data;} private static final DataHolder holder = new DataHolder(); public static DataHolder getInstance() {return holder;} } 

De l’activité lancée:

 Ssortingng data = DataHolder.getInstance().getData(); 

Utiliser le singleton d’application

L’application singleton est une instance de android.app.Application créée lors du lancement de l’application. Vous pouvez fournir un personnalisé en étendant l’ Application :

 import android.app.Application; public class MyApplication extends Application { private Ssortingng data; public Ssortingng getData() {return data;} public void setData(Ssortingng data) {this.data = data;} } 

Avant de lancer l’activité:

 MyApplication app = (MyApplication) getApplicationContext(); app.setData(someData); 

Ensuite, de l’activité lancée:

 MyApplication app = (MyApplication) getApplicationContext(); Ssortingng data = app.getData(); 

Champs statiques

L’idée est fondamentalement la même que le singleton, mais dans ce cas, vous fournissez un access statique aux données:

 public class DataHolder { private static Ssortingng data; public static Ssortingng getData() {return data;} public static Ssortingng setData(Ssortingng data) {DataHolder.data = data;} } 

De l’activité lancée:

 Ssortingng data = DataHolder.getData(); 

HashMap de WeakReferences

Même idée, mais en permettant au ramasse-miettes de supprimer les objects non référencés (par exemple lorsque l’utilisateur quitte l’activité):

 public class DataHolder { Map> data = new HashMap>(); void save(Ssortingng id, Object object) { data.put(id, new WeakReference(object)); } Object resortingeve(Ssortingng id) { WeakReference objectWeakReference = data.get(id); return objectWeakReference.get(); } } 

Avant de lancer l’activité:

 DataHolder.getInstance().save(someId, someObject); 

De l’activité lancée:

 DataHolder.getInstance().resortingeve(someId); 

Vous pouvez ou non avoir à passer l’ID d’object en utilisant les options de l’intention. Tout dépend de votre problème spécifique.

Persister des objects sur le disque

L’idée est de sauvegarder les données sur le disque avant de lancer l’autre activité.

Avantages: vous pouvez lancer l’activité depuis d’autres endroits et, si les données sont déjà persistantes, cela devrait fonctionner correctement.

Inconvénients: c’est lourd et prend plus de temps à mettre en œuvre. Nécessite plus de code et donc plus de chance d’introduire des bogues. Ce sera aussi beaucoup plus lent.

Parmi les moyens de persister les objects, citons:

  • Enregistrez-les dans les préférences partagées
  • Enregistrez-les dans une firebase database sqlite
  • Enregistrez-les dans un fichier (j’éviterais celui-ci)

Qu’est-ce que vous pouvez utiliser:

  1. passer des données entre les activités (comme l’a dit Cristian)
  2. utiliser une classe avec beaucoup de variables statiques (vous pouvez donc les appeler sans instance de la classe et sans utiliser getter / setter)
  3. Utiliser une firebase database
  4. Préférences partagées

Ce que vous choisissez dépend de vos besoins. Vous utiliserez probablement plus d’une façon lorsque vous avez “beaucoup de”

Faites ce que google vous commande de faire! ici: http://developer.android.com/resources/faq/framework.html#3

  • Types de données primitifs
  • Objets non persistants
  • Classe Singleton – mon préféré: D
  • Un champ / une méthode statique publique
  • Un HashMap de WeakReferences aux objects
  • Objets persistants (Préférences d’application, Fichiers, ContentProviders, SQLite DB)

“Cependant, je souhaite partager beaucoup de variables et certaines pourraient être assez volumineuses, donc je ne veux pas en créer des copies comme ci-dessus.”

Cela ne fait pas de copie (en particulier avec Ssortingng , mais même les objects sont valables par rapport à la référence, pas l’object lui-même, et les getter comme ceux-ci peuvent être utilisés). bien compris). Les anciens «mythes de performance», tels que 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 le faire, vous pouvez également rendre les variables publiques ou protégées dans GlobalState et y accéder directement. Et, vous pouvez créer un singleton statique comme object Application JavaDoc indique :

Il n’y a normalement pas besoin de sous-classe Application. Dans la plupart des cas, les singletons statiques peuvent fournir les mêmes fonctionnalités de manière plus modulaire. Si votre singleton a besoin d’un contexte global (par exemple pour enregistrer des récepteurs de diffusion), la fonction permettant de le récupérer peut recevoir un contexte qui utilise en interne Context.getApplicationContext () lors de la première construction du singleton.

L’utilisation des données d’ intention , comme d’autres réponses ici, est une autre façon de transmettre des données, mais elle est généralement utilisée pour les données plus petites et les types simples. Vous pouvez transmettre des données plus grandes / plus complexes, mais cela implique plus que de simplement utiliser un singleon statique. L’object Application rest mon favori personnel pour le partage de données non persistantes plus grandes / plus complexes entre les composants d’une application Android (car son cycle de vie est 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.

Vous pouvez étendre la classe et le tag Application sur tous les objects que vous souhaitez, ils sont alors disponibles n’importe où dans votre application.

L’utilisation du hashmap 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 scope l’affectez-vous? Étant donné que la structure contrôle le cycle de vie de l’activité, le fait d’avoir l’une des activités participantes lui fait courir des risques d’exécution lorsque le propriétaire est détruit avant ses clients. Si l’application le possède, une activité doit explicitement supprimer cette entrée pour éviter que le hashmap ne contienne des entrées avec une clé valide et une référence faible collectée potentiellement exploitable. 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 dans un singleton est un meilleur choix. Une valeur dans la carte est accessible via un object clé, et lorsqu’aucune référence solide à la clé n’existe (par exemple, toutes les activités sont effectuées avec la clé et ce à quoi elle correspond), le GC peut récupérer l’entrée de la carte.

Eh bien, j’ai quelques idées, mais je ne sais pas si elles sont ce que vous cherchez.

Vous pouvez utiliser un service qui contient toutes les données, puis lier simplement vos activités au service pour resortingver les données.

Ou regroupez vos données dans un fichier sérialisable ou parcelable et joignez-les à un ensemble et transmettez-le entre les activités.

Celui-ci n’est peut-être pas du tout ce que vous cherchez, mais vous pouvez également essayer d’utiliser des préférences partagées ou une préférence en général.

De toute façon laissez-moi savoir ce que vous décidez.

En supposant que vous appelez l’activité 2 de l’activité 1 en utilisant une intention.
Vous pouvez transmettre les données avec intent.putExtra (),

Prenez ceci pour votre référence. Envoi de tableaux avec Intent.putExtra

J’espère que c’est ce que vous voulez.

Si vous souhaitez appeler d’autres activités à partir de l’activité en cours, vous devez utiliser les intentions . Vous pourriez vous concentrer moins sur la persistance des données que sur leur partage en fonction des besoins.

Cependant, si vous devez vraiment conserver ces valeurs, vous pouvez les conserver dans un fichier texte structuré ou une firebase database 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és lors de la création d’activités. N’oubliez pas également que vous avez SQLite sur tous les appareils Android, vous pouvez donc les stocker dans une table de firebase database. Vous pouvez également utiliser une carte pour stocker des paires clé-valeur et sérialiser la carte sur un stockage local, mais cela peut être trop lourd pour être utile pour des structures de données simples.

Toutes les réponses ci-dessus sont excellentes … J’ajoute juste une réponse que personne n’a encore mentionnée à propos des données persistantes à travers les activités, à savoir utiliser la firebase database SQLite intégrée à Android pour conserver les données pertinentes … databaseHelper dans l’état de l’application et appelez-le selon vos besoins. Ou créez simplement une classe d’assistance et effectuez les appels de la firebase database lorsque vous en avez besoin … Ajoutez simplement une autre couche à prendre en compte … Mais toutes les autres réponses suffiraient aussi bien .. Préférence vraiment juste

Partage de données entre activités par exemple, passage d’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

 Intent openLoginActivity = new Intent(getBaseContext(), Home.class); openLoginActivity.putExtra("email", getEmail); 

2 codes sur la page d’accueil

 Bundle extras = getIntent().getExtras(); accountEmail = extras.getSsortingng("email"); 

Il existe différents moyens de partager des données entre les activités

1: Transmission des données entre les activités à l’aide de l’intention

 Intent intent=new Intent(this, desirableActivity.class); intent.putExtra("KEY", "Value"); startActivity(intent) 

2: En utilisant le mot-clé static, définissez la variable comme public static et utilisez n’importe où dans le projet

  public static int sInitialValue=0; 

utiliser n’importe où dans le projet en utilisant classname.variableName;

3: Utilisation de la firebase database

mais son processus un peu long, vous devez utiliser une requête pour insérer des données et itérer des données en utilisant le curseur lorsque cela est nécessaire. 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 firebase database. mais il y a une certaine limitation, vous ne pouvez pas enregistrer ArrayList, List et les objects custome.

5: Créez le setter de lecture dans la classe Aplication et accédez à n’importe où dans le projet.

  private Ssortingng data; public Ssortingng getData() { return data; } public void setData(Ssortingng data) { this.data = data; } 

ici mis et obtenir des activités

  ((YourApplicationClass)getApplicationContext()).setData("abc"); Ssortingng data=((YourApplicationClass)getApplicationContext()).getData(); 

Et si vous voulez travailler avec des objects de données, ces deux outils sont très importants:

Serializable vs Parcelable

  • Serializable est une interface de marqueur, ce qui implique que l’utilisateur ne peut pas rassembler les données en fonction de leurs besoins. Ainsi, lorsque l’object implémente, Serializable Java va automatiquement le sérialiser.
  • Parcelable est le protocole de sérialisation propre à Android. Dans Parcelable, les développeurs écrivent du code personnalisé pour marshaling et unmarshaling. Donc, il crée moins d’objects parasites que la sérialisation
  • Les performances de Parcelable sont très élevées par rapport à Serializable en raison de son implémentation personnalisée. Il est fortement recommandé d’utiliser l’implantation Parcelable lors de la sérialisation d’objects dans Android.

public class User implements Parcelable

vérifier plus ici