256 votes

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

hey les gens, J'ai une activité qui est la principale activité tout au long de l'application et a un certain nombre de variables. J'ai 2 autres activités que je voudrais être en mesure d'utiliser les données de la première activité. Maintenant, je sais que je peux faire quelque chose comme ceci:

GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();

Cependant, je veux partager beaucoup de variables et certains peuvent être assez grande donc je ne veux pas être la création de copies d'entre eux, comme ci-dessus. Donc est-il possible d'obtenir directement et de changer les variables sans l'aide de méthodes get et set que je me souviens de la lecture d'un article sur le google site dev en disant: ce n'est pas recommandé pour les performances sur android.

Donc si quelqu'un a des idées ou connaît une meilleure façon que je l'apprécierais. Merci.

495voto

Cristian Points 92147

Voici une compilation des plus commun des moyens pour y parvenir:

  • Envoyer des données à l'intérieur de l'intention
  • Utiliser une classe singleton
  • L'utilisation de l'application singleton
  • Les champs statiques
  • HashMap d' WeakReferences
  • Conserver les objets (sqlite, de partager des préférences, fichier, etc.)

TL;DR: il y a deux façons de partage de données: la transmission des données à l'intention des figurants ou de le sauvegarder quelque part d'autre. Si les données sont primitives, des Chaînes ou des objets définis par l'utilisateur: l'envoyer en tant que partie de l'intention extras (objets définis par l'utilisateur doit mettre en oeuvre Parcelable). Si le passage d'objets complexes enregistrer une instance dans un singleton quelque part d'autre et d'y accéder depuis le lancement de l'activité.

Quelques exemples de comment et pourquoi mettre en place de chaque approche:

Envoyer des données à l'intérieur d'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");
String value2 = bundle.getString("some_other_key");

Utilisez cette méthode si vous êtes de passage de données primitifs ou des Chaînes de caractères. Vous pouvez également passer des objets qui implémente Serializable.

Bien que tentant, vous devriez réfléchir à deux fois avant d'utiliser Serializable: c'est sujette aux erreurs et horriblement lent. Donc, en général: rester à l'écart de Serializable si possible. Si vous souhaitez passer des complexes d'objets définis par l'utilisateur, prendre un coup d'oeil à l' Parcelable interface. Il est plus difficile à mettre en œuvre, mais il a considérable gain de vitesse par rapport à l' Serializable.

Partager des données sans la persistance de disque

Il est possible de partager des données entre des activités en l'enregistrant dans la mémoire étant donné que, dans la plupart des cas, les deux activités exécutées 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 connu des cas dans lesquels android des tentatives de lancement de la dernière activité à l'aide de l'intention avant l'application a été tué. Dans ce cas, les données stockées dans un singleton (les vôtres ou Application) aura disparu et les mauvaises choses peuvent se produire. Pour éviter de tels cas, vous pouvez soit conserver les objets de disque ou de vérifier les données avant de les utiliser afin de vous assurer de la validité de son.

Utiliser une classe singleton

Avoir une classe à un ensemble de données:

public class DataHolder {
  private String data;
  public String getData() {return data;}
  public void setData(String data) {this.data = data;}

  private static final DataHolder holder = new DataHolder();
  public static DataHolder getInstance() {return holder;}
}

Depuis le lancement de l'activité:

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

L'utilisation de l'application singleton

L'application singleton est une instance de l' android.app.Application qui est créé lorsque l'application est lancée. Vous pouvez fournir un programme personnalisé en étendant Application:

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

Avant le lancement de l'activité:

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

Puis, à partir du lancement de l'activité:

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

Les champs statiques

L'idée est fondamentalement que le singleton, mais dans ce cas, vous fournir statique d'accès aux données:

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

Depuis le lancement de l'activité:

String data = DataHolder.getData();

HashMap d' WeakReferences

Même idée, mais en permettant le garbage collector supprimer les objets non référencés (par exemple, lorsque l'utilisateur quitte l'activité):

public class DataHolder {
  Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();

  void save(String id, Object object) {
    data.put(id, new WeakReference<Object>(object));
  }

  Object retrieve(String id) {
    WeakReference<Object> objectWeakReference = data.get(id);
    return objectWeakReference.get();
  }
}

Avant le lancement de l'activité:

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

Depuis le lancement de l'activité:

DataHolder.getInstance().retrieve(someId);

Vous peut ou peut ne pas avoir à passer l'id de l'objet à l'aide de l'intention des figurants. Tout dépend de votre problème spécifique.

Conserver les objets sur le disque

L'idée est d'enregistrer les données dans le 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à persisté, il devrait fonctionner très bien.

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. Il sera aussi beaucoup plus lent.

Certains des moyens de conserver les objets comprennent:

24voto

WarrenFaith Points 28137

Ce que vous pouvez utiliser:

  1. le passage des données entre les activités (comme Cristian dit)
  2. à l'aide d'une classe avec beaucoup de variables statiques (de sorte que vous pouvez les appeler sans une instance de la classe et sans l'aide de getter/setter)
  3. À l'aide d'une base de données
  4. Partagé Préférences

Ce que vous choisissez dépend de vos besoins. Probablement, vous permettra d'utiliser plus d'une façon, lorsque vous avez "beaucoup de"

16voto

Tylko Arka Gdynia Points 171

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

Les Types De Données Primitifs Non-Objets Persistants Classe Singleton - mon préféré :D Un public static field/méthode Une table de hachage de WeakReferences à des Objets Les Objets persistants ( Préférences de l'Application, les Fichiers,les contentProviders,SQLite DB)

14voto

Charlie Collins Points 4942

"Cependant, je veux partager beaucoup de variables et certains sont peut-être plutôt grand donc je ne veux pas être la création d' des copies d'eux, comme ci-dessus."

Ce n'est pas faire une copie (en particulier avec la Chaîne, mais même les objets sont passer par la valeur de la référence, et non l'objet lui-même, et les getter est comme qui sont beaux à utiliser -- sans doute mieux que les autres, parce qu'ils sont communs et bien compris). L'ancien "performance mythes," comme ne pas utiliser les accesseurs et mutateurs, ont encore une certaine valeur, mais ont également été mis à jour dans les docs.

Mais si vous ne voulez pas le faire, vous pourriez tout aussi bien faire l'variables public ou protégé en GlobalState et d'y accéder directement. Et, vous pouvez faire un static singleton comme l' objet de l'Application de JavaDoc indique:

Il n'est normalement pas besoin de sous-classe Application. Dans la plupart des situation, statique des singletons peuvent fournir les mêmes la fonctionnalité dans un plus modulaire. Si votre singleton mondiale contexte (par exemple pour vous inscrire récepteurs de radiodiffusion), la fonction de récupérer il peut être dans un Contexte donné qui utilise en interne Contexte.getcontexteapplication() lorsque d'abord la construction de l'singleton.

En utilisant l'Intention de données, comme d'autres réponses ici note est une autre façon de transmettre les données, mais il est généralement utilisé pour les petits de données et les types simples. Vous pouvez passer la plus grande/plus de données complexes, mais c'est plus compliqué que de simplement en utilisant un statique singleon. La Demande d' objet est toujours mon favori personnel pour le partage de la plus grande/plus complexes non persistant de données entre les composants de l'application Android mais (parce qu'il a un sens bien défini cycle de vie d'une application Android).

Aussi, comme d'autres l'ont noté, si les données est très complexe et doit être persistante , alors vous pouvez utiliser SQLite ou le système de fichiers trop.

7voto

Jimmy Points 5021

Vous pouvez étendre l' Application de la classe et de tag sur tous les objets que vous voulez il ya, ensuite, ils sont disponibles n'importe où dans votre application

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X