2012-05-16 4 views
3

J'ai une application Android, où il y a quelques activités. Chacune des activités télécharge un flux xml/json, l'analyse et l'envoie à un singleton, généralement en tant qu'articliste.Problèmes avec singleton en android

Cependant, après avoir passé par diverses activités, il semble que le singleton est en train de mourir et que la plupart des listes de tableaux téléchargées précédemment sont maintenant vides. Pourquoi est-ce vrai? Le singleton n'est-il pas une pratique recommandée pour le partage de données entre les activités?

+0

Pouvez-vous poster du code de votre classe Singleton? J'utilise une solution similaire sans aucun problème. – mouser58907

+2

Si vous souhaitez conserver une variable globale entre activités, conservez-la dans Application. Étendez une classe à partir de Application et ajoutez-la dans votre fichier AnddroidManifest. – Tarun

+0

La suggestion de Tarun est une bonne façon de le faire sur Android, mais il n'y a aucune raison que votre singleton ne fonctionne pas aussi bien. Je suis avec Mouser, si vous pouviez partager votre code, nous allons jeter un coup d'oeil. – kcoppock

Répondre

2

S'il vous plaît voir ce fil de Android API FAQ, ici vous trouverez sûrement la solution la plus adaptée à votre problème (si vous avez besoin d'un court-vie ou une donnée de longue durée).

Les singletons sont utilisés pour les objets à cycle de vie court.

Modifier: S'il vous plaît garder à l'esprit que, pour grande quantité de données, il est toujours une meilleure idée d'utiliser les bases de données/structurated fichiers locaux (bien que ces derniers sont consommateur en ressources pour lecture/écriture). Et si vous travaillez avec un objet très complexe, choisir SharedPreferences peut aussi causer des maux de tête.

Un échantillon de stockage/chargement d'une liste de SharedPreferences:

// the name with which to store the shared preference 
public static final String PERSON_LIST = "my.personlist"; 

// a sample data structure that will be stored 
public static final class Person 
{ 
    private String name; 
    private int age; 

    public String toString() 
    { 
     return name + "|" + age; 
    } 

    // splits the passed String parameter, and retrieves the members 
    public static Person loadPersonFromString(final String personString) 
    { 
     final Person p = new Person(); 
     final String[] data = personString.split("|"); 
     p.name = data[0]; 
     p.age = Integer.parseInt(data[1]); 
     return p; 
    } 
} 

/** 
* Saves the current list of Persons in SharedPreferences 
* @param persons: the list to save 
*/ 
public void savePersonList(final ArrayList<Person> persons) 
{ 
    final SharedPreferences prefs = PreferenceManager. 
     getDefaultSharedPreferences(getApplicationContext()); 
    final Editor editor = prefs.edit(); 
    final StringBuilder builder = new StringBuilder(); 
    for (final Person person : persons) 
    { 
     if (builder.length() > 0) 
      builder.append("-Person-"); 
     builder.append(person.toString()); 
    } 
    editor.putString(PERSON_LIST, builder.toString()); 
    editor.commit(); 
} 

/** 
* Loads the list of Persons from SharedPreferences 
* @return the loaded list 
*/ 
public ArrayList<Person> loadPersonList() 
{ 
    final SharedPreferences prefs = PreferenceManager. 
     getDefaultSharedPreferences(getApplicationContext()); 
    final ArrayList<Person> persons = new ArrayList<Menu.Person>(); 
    final String[] array = prefs.getString(PERSON_LIST, "").split("-Person-"); 
    for (final String personString : array) 
    { 
     if (personString.length() > 0) 
      persons.add(Person.loadPersonFromString(personString)); 
    } 
    return persons; 
} 
+0

donc nous devrions vérifier si les objets existent et repeuplent le singleton? – Azlam

+0

en fait je voudrais un stockage persistant, et si vous ne voulez pas déranger avec la conception de base de données et dml, alors le mieux serait d'utiliser les préférences de l'application: 'SharedPreferences'. Avec un override (parsable) 'toString()' personnalisé, vous pouvez y stocker toutes les listes importantes dont vous avez besoin. 'SharedPreferences' sont toujours conservés, faciles d'accès et fournissent toujours la dernière valeur réelle, quelle que soit l'activité à laquelle vous les récupérez. Au-dessus, vous pouvez enregistrer les auditeurs pour qu'ils vous avertissent lorsque quelque chose change. – rekaszeru

+0

avez-vous un exemple ou si vous pouvez poster un extrait du code de la façon d'implémenter reversable parsable? – Tarun

1

Vous pouvez initialiser via une classe Application. Cette classe est présente dans toutes les activités. Vous devez le déclarer dans le fichier manifeste et avoir un cycle de vie similaire à une activité.

Documentation ici: Application

Hope it helps.

JQcorreia

3

Ajouter mon commentaire comme une réponse

Si vous souhaitez conserver une variable globale dans toutes les activités garder alors que dans la demande. Étendez une classe à partir de Application et ajoutez-la dans votre fichier AnddroidManifest.

De la FAQ API Android partagée par @rekaszeru

Singleton classe

Vous pouvez profiter du fait que vos composants d'application d'exécution dans le même processus par l'utilisation d'un singleton . C'est une classe conçue pour avoir une seule instance. Il a une méthode statique avec un nom tel que getInstance() qui retourne l'instance; La première fois que cette méthode est appelée, elle crée l'instance globale. Étant donné que tous les appelants obtiennent la même instance, ils peuvent l'utiliser comme point d'interaction . Par exemple, l'activité A peut récupérer l'instance et appeler setValue (3); l'activité B ultérieure peut récupérer l'instance et appelle getValue() pour récupérer la dernière valeur définie.