Comment déclarer des variables globales dans Android?

595

Je crée une application qui nécessite une connexion. J'ai créé l'activité principale et la connexion.

Dans la onCreateméthode d' activité principale, j'ai ajouté la condition suivante:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ...

    loadSettings();
    if(strSessionString == null)
    {
        login();
    }
    ...
}

La onActivityResultméthode qui est exécutée lorsque le formulaire de connexion se termine ressemble à ceci:

@Override
public void onActivityResult(int requestCode,
                             int resultCode,
                             Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode)
    {
        case(SHOW_SUBACTICITY_LOGIN):
        {
            if(resultCode == Activity.RESULT_OK)
            {

                strSessionString = data.getStringExtra(Login.SESSIONSTRING);
                connectionAvailable = true;
                strUsername = data.getStringExtra(Login.USERNAME);
            }
        }
    }

Le problème est que le formulaire de connexion apparaît parfois deux fois (la login()méthode est appelée deux fois) et également lorsque le clavier du téléphone glisse, le formulaire de connexion apparaît à nouveau et je suppose que le problème est la variable strSessionString.

Quelqu'un sait-il comment définir la variable globale afin d'éviter que le formulaire de connexion n'apparaisse après que l'utilisateur s'est déjà authentifié avec succès?

Niko Gamulin
la source
un bon tutoriel sur la façon de gérer un état d'activité à l'aide du bundle d'état d'instance enregistré quicktips.in/…
Deepak Swami

Réponses:

954

J'ai écrit cette réponse en '09 quand Android était relativement nouveau, et il y avait beaucoup de domaines mal établis dans le développement Android. J'ai ajouté un long addendum au bas de cet article, adressant certaines critiques et détaillant un désaccord philosophique que j'ai avec l'utilisation de Singletons plutôt que de sous-classer Application. Lisez-le à vos risques et périls.

RÉPONSE ORIGINALE:

Le problème plus général que vous rencontrez est de savoir comment enregistrer l'état sur plusieurs activités et toutes les parties de votre application. Une variable statique (par exemple, un singleton) est un moyen Java courant d'y parvenir. J'ai cependant constaté qu'une manière plus élégante dans Android consiste à associer votre état au contexte de l'application.

Comme vous le savez, chaque Activité est également un Contexte, qui est une information sur son environnement d'exécution au sens large. Votre application a également un contexte et Android garantit qu'elle existera en tant qu'instance unique dans votre application.

La façon de procéder consiste à créer votre propre sous-classe de android.app.Application , puis à spécifier cette classe dans la balise d'application de votre manifeste. Désormais, Android créera automatiquement une instance de cette classe et la rendra disponible pour l'ensemble de votre application. Vous pouvez y accéder à partir de tout en contextutilisant la Context.getApplicationContext()méthode ( Activityfournit également une méthode getApplication()qui a exactement le même effet). Voici un exemple extrêmement simplifié, avec des mises en garde à suivre:

class MyApp extends Application {

  private String myState;

  public String getState(){
    return myState;
  }
  public void setState(String s){
    myState = s;
  }
}

class Blah extends Activity {

  @Override
  public void onCreate(Bundle b){
    ...
    MyApp appState = ((MyApp)getApplicationContext());
    String state = appState.getState();
    ...
  }
}

Cela a essentiellement le même effet que l'utilisation d'une variable statique ou singleton, mais s'intègre assez bien dans le cadre Android existant. Notez que cela ne fonctionnera pas entre les processus (si votre application est l'une des rares à avoir plusieurs processus).

Quelque chose à noter dans l'exemple ci-dessus; supposons que nous avions plutôt fait quelque chose comme:

class MyApp extends Application {

  private String myState = /* complicated and slow initialization */;

  public String getState(){
    return myState;
  }
}

Maintenant, cette lente initialisation (comme frapper le disque, frapper le réseau, tout ce qui bloque, etc.) sera effectuée chaque fois que l'application est instanciée! Vous pensez peut-être que ce n'est qu'une fois pour le processus et que je devrai quand même en payer le coût, non? Par exemple, comme Dianne Hackborn le mentionne ci-dessous, il est tout à fait possible que votre processus soit instancié - juste - pour gérer un événement de diffusion en arrière-plan. Si votre traitement de diffusion n'a pas besoin de cet état, vous venez potentiellement d'effectuer toute une série d'opérations compliquées et lentes pour rien. L'instanciation paresseuse est le nom du jeu ici. Ce qui suit est une façon légèrement plus compliquée d'utiliser Application qui a plus de sens pour tout sauf la plus simple des utilisations:

class MyApp extends Application {

  private MyStateManager myStateManager = new MyStateManager();

  public MyStateManager getStateManager(){
    return myStateManager ;
  }
}

class MyStateManager {

  MyStateManager() {
    /* this should be fast */
  }

  String getState() {
    /* if necessary, perform blocking calls here */
    /* make sure to deal with any multithreading/synchronicity issues */

    ...

    return state;
  }
}

class Blah extends Activity {

  @Override
  public void onCreate(Bundle b){
    ...
    MyStateManager stateManager = ((MyApp)getApplicationContext()).getStateManager();
    String state = stateManager.getState();
    ...
  }
}

Bien que je préfère la sous-classe d'application à l'utilisation de singletons ici comme solution plus élégante, je préférerais que les développeurs utilisent des singletons si c'est vraiment nécessaire plutôt que de réfléchir du tout sur les performances et les implications multithreads de l'association de l'état à la sous-classe d'application.

REMARQUE 1: également comme anticafe a commenté, afin de lier correctement votre remplacement d'application à votre application, une balise est nécessaire dans le fichier manifeste. Encore une fois, consultez les documents Android pour plus d'informations. Un exemple:

<application
     android:name="my.application.MyApp" 
     android:icon="..."
     android:label="...">
</application>

REMARQUE 2: user608578 demande ci-dessous comment cela fonctionne avec la gestion des cycles de vie des objets natifs. Je ne suis pas du tout au courant de l'utilisation du code natif avec Android, et je ne suis pas qualifié pour répondre à la façon dont cela interagirait avec ma solution. Si quelqu'un a une réponse à cela, je suis prêt à lui attribuer le mérite et à mettre les informations dans ce message pour une visibilité maximale.

ADDENDA:

Comme certaines personnes l'ont noté, ce n'est pas une solution pour un état persistant , quelque chose que j'aurais peut-être dû souligner davantage dans la réponse originale. C'est-à-dire que ce n'est pas censé être une solution pour enregistrer l'utilisateur ou d'autres informations qui doivent être conservées pendant la durée de vie des applications. Ainsi, je considère que la plupart des critiques ci-dessous concernent les applications tuées à tout moment, etc. Il est censé être une solution pour stocker l'état d'application temporaire, facilement recréable (qu'un utilisateur soit connecté par exemple) et les composants qui sont de nature unique (gestionnaire de réseau d'application par exemple) ( PAS singleton!).

Dayerman a eu la gentillesse de signaler une conversation intéressante avec Reto Meier et Dianne Hackborn dans laquelle l'utilisation des sous-classes d'application est déconseillée en faveur des modèles Singleton. Somatik a également souligné quelque chose de cette nature plus tôt, même si je ne l'avais pas vu à l'époque. En raison des rôles de Reto et Dianne dans la maintenance de la plate-forme Android, je ne peux pas recommander de bonne foi d'ignorer leurs conseils. Ce qu'ils disent, va. Je ne suis pas d'accord avec les opinions exprimées concernant la préférence pour Singleton aux sous-classes d'application. Dans mon désaccord, je vais utiliser les concepts les mieux expliqués dans cette explication StackExchange du modèle de conception Singleton, de sorte que je n'ai pas à définir de termes dans cette réponse. J'encourage fortement à parcourir le lien avant de continuer. Point par point:

Dianne déclare: "Il n'y a aucune raison de sous-classer Application. Ce n'est pas différent que de faire un singleton ..." Cette première affirmation est incorrecte. Il y a deux raisons principales pour cela. 1) La classe Application offre une meilleure garantie à vie pour un développeur d'applications; il est garanti d'avoir la durée de vie de l'application. Un singleton n'est pas EXPLICITEMENT lié à la durée de vie de l'application (bien qu'il le soit effectivement). Cela peut ne pas être un problème pour votre développeur d'applications moyen, mais je dirais que c'est exactement le type de contrat que l'API Android devrait offrir, et il offre également beaucoup plus de flexibilité au système Android, en minimisant la durée de vie des applications associées. Les données. 2) La classe Application fournit au développeur d'application un seul titulaire d'instance pour l'état, ce qui est très différent d'un titulaire d'État Singleton. Pour une liste des différences, voir le lien d'explication Singleton ci-dessus.

Dianne poursuit: "... c'est probablement quelque chose que vous regretterez à l'avenir alors que vous trouvez que votre objet Application devient ce gros gâchis enchevêtré de ce qui devrait être une logique d'application indépendante." Ce n'est certainement pas incorrect, mais ce n'est pas une raison pour choisir Singleton plutôt que la sous-classe Application. Aucun des arguments de Diane ne fournit une raison pour laquelle l'utilisation d'un Singleton est meilleure qu'une sous-classe Application, tout ce qu'elle tente d'établir est que l'utilisation d'un Singleton n'est pas pire qu'une sous-classe Application, ce qui, à mon avis, est faux.

Elle poursuit: "Et cela conduit plus naturellement à la façon dont vous devriez gérer ces choses - en les initialisant à la demande." Cela ignore le fait qu'il n'y a aucune raison pour laquelle vous ne pouvez pas initialiser à la demande à l'aide d'une sous-classe d'application également. Encore une fois, il n'y a aucune différence.

Dianne termine avec "Le framework lui-même a des tonnes et des tonnes de singletons pour toutes les petites données partagées qu'il maintient pour l'application, telles que les caches de ressources chargées, les pools d'objets, etc. Il fonctionne très bien." Je ne dis pas que l'utilisation de Singletons ne peut pas fonctionner correctement ou n'est pas une alternative légitime. Je soutiens que les singletons ne fournissent pas un contrat aussi solide avec le système Android que l'utilisation d'une sous-classe d'application, et en outre que l'utilisation de singletons indique généralement une conception inflexible, qui n'est pas facilement modifiable, et conduit à de nombreux problèmes sur la route. À mon humble avis, le contrat solide que l'API Android offre aux applications de développement est l'un des aspects les plus attrayants et les plus agréables de la programmation avec Android, et a contribué à une adoption précoce par les développeurs, ce qui a conduit la plate-forme Android au succès qu'elle connaît aujourd'hui.

Dianne a également commenté ci-dessous, mentionnant un inconvénient supplémentaire à l'utilisation des sous-classes d'application, elles peuvent encourager ou faciliter l'écriture de code de performances inférieur. C'est très vrai, et j'ai édité cette réponse pour souligner l'importance de considérer la perf ici et d'adopter la bonne approche si vous utilisez le sous-classement d'application. Comme l'indique Dianne, il est important de se rappeler que votre classe Application sera instanciée à chaque fois que votre processus est chargé (pourrait être plusieurs fois à la fois si votre application s'exécute dans plusieurs processus!) Même si le processus n'est chargé que pour une diffusion en arrière-plan un événement. Il est donc important d'utiliser la classe Application plus comme référentiel pour les pointeurs vers les composants partagés de votre application plutôt que comme un endroit pour effectuer n'importe quel traitement!

Je vous laisse avec la liste suivante des inconvénients des Singletons, volés à partir du lien StackExchange précédent:

  • Incapacité à utiliser des classes abstraites ou d'interface;
  • Incapacité de sous-classe;
  • Couplage élevé à travers l'application (difficile à modifier);
  • Difficile à tester (ne peut pas simuler / se moquer des tests unitaires);
  • Difficile à paralléliser en cas d'état mutable (nécessite un verrouillage important);

et ajouter le mien:

  • Contrat à vie imprécis et ingérable inadapté au développement Android (ou la plupart des autres);
sooniln
la source
93
Merci Soonil - ce genre de réponses est la raison pour laquelle j'aime tellement Stack Overflow. BON TRAVAIL!
JohnnyLambada
5
Pour tous ceux qui se demandent comment "spécifier cette classe dans la balise d'application de votre manifeste", il existe, à ce jour, deux autres réponses à cette question qui décrivent comment le faire (utilisez android: name), une par ebuprofen et une par Mike Brown.
Tyler Collier
9
Bientôt, votre réponse est juste, mais pourriez-vous remarquer que nous devrions ajouter <application android: name = ". MyApp" ... /> dans le fichier manifeste Android?
anticafe
12
Permettez-moi de répéter une fois de plus, vous ne devriez pas utiliser Application for global. Il ne sert à rien, ne présente aucun avantage par rapport aux singletons et peut être activement nuisible, comme nuire aux performances de lancement de votre processus. Au moment de la création de l'application, vous ne savez pas à quoi sert votre processus. En initialisant paresseusement des singletons selon vos besoins, vous n'avez qu'à effectuer le travail nécessaire. Par exemple, si votre processus est lancé pour gérer une diffusion concernant un événement d'arrière-plan, il n'y a aucune raison d'initialiser l'état global requis par votre interface utilisateur.
hackbod
14
Soyons également très clairs ici - tous vos arguments contre les singletons sont parfaitement valables, lorsque nous parlons de situations où vous choisissez réellement entre un singleton et une autre approche qui n'est pas globale; les singletons sont des globaux, avec toutes les mises en garde concernant les globaux qui s'appliquent. Cependant, Application est également un singleton . Vous n'échappez pas à ces problèmes en passant à l'application de sous-classement, une application est exactement la même chose qu'un singleton (mais pire), cela vous permet simplement de vous tromper que vous faites quelque chose de plus propre. Mais tu ne l'es pas.
hackbod
153

Créer cette sous-classe

public class MyApp extends Application {
  String foo;
}

Dans AndroidManifest.xml, ajoutez android: nom

Exemple

<application android:name=".MyApp" 
       android:icon="@drawable/icon" 
       android:label="@string/app_name">
Guillaume
la source
1
Merci pour ça. Je me demandais comment le déclarer dans le manifeste
Someone Somewhere
3
Pour que cela fonctionne pour moi, j'ai dû supprimer le "." dans ".MyApp"
Quelqu'un Quelque part
3
il suffit de le déclarer après l'activité principale, sinon il risque de ne pas s'installer / se déployer
sami
11
je veux juste dire, cela va dans la balise d'application MAIN qui est déjà là ... ce n'est pas une seconde :) a dû apprendre à la dure.
bwoogie
java.lang.IllegalAccessException: access to class is not allowed
Raptor
142

La façon suggérée par Soonil de conserver un état pour l'application est bonne, mais elle a un point faible - il y a des cas où le système d'exploitation tue tout le processus de demande. Voici la documentation à ce sujet - Processus et cycles de vie .

Prenons un cas - votre application passe en arrière-plan parce que quelqu'un vous appelle (l'application Téléphone est maintenant au premier plan). Dans ce cas && sous d'autres conditions (vérifiez le lien ci-dessus pour ce qu'elles pourraient être), le système d'exploitation peut tuer votre processus de demande, y compris l' Applicationinstance de sous - classe. En conséquence, l'État est perdu. Lorsque vous reviendrez ultérieurement à l'application, le système d'exploitation restaurera sa pile d'activité et son Applicationinstance de sous - classe, quel que soit le myStatechamp null.

AFAIK, le seul moyen de garantir la sécurité de l'État est d'utiliser toute sorte de persistance de l'État, par exemple en utilisant un privé pour le fichier d'application ou SharedPrefernces(il utilise finalement un privé pour le fichier d'application dans le système de fichiers interne).

Vit Khudenko
la source
10
+1 pour persister avec SharedPreferences; c'est comme ça que je l'ai vu faire. Je trouve étrange d'abuser du système de préférence pour l'état enregistré, mais cela fonctionne si bien que le problème ne devient qu'une question de terminologie.
Cheezmeister
1
pourriez-vous s'il vous plaît poster le code (ou fournir un lien vers une explication) sur la façon dont SharedPreferences est utilisé pour résoudre le problème décrit par Arhimed
Quelqu'un Quelque Part Quelque part
2
Préférences, base de données, sérialisation de fichiers, etc. Chaque activité peut conserver son état si elle utilise onSaveInstanceState mais cela n'aidera pas si l'utilisateur se retire de l'activité et qui la supprime de la pile d'historique, force la fermeture ou éteint son appareil .
Darren Hinderer
1
Ce comportement est très ennuyeux - il ne serait pas si mauvais si la méthode onTerminate () de votre application était appelée afin que vous puissiez gérer la situation avec élégance.
Dean Wild
2
C'est la bonne réponse à mon avis. C'est un bug de s'appuyer sur la même instance d'application existant entre les activités. D'après mon expérience, il est assez courant pour Android de détruire complètement et de recréer l'ensemble de votre processus pendant que vous êtes en arrière-plan. Être en arrière-plan peut simplement signifier lancer une intention de caméra, une intention de navigateur ou recevoir un appel téléphonique.
Jared Kells
26

Juste une note ..

ajouter:

android:name=".Globals"

ou tout ce que vous avez nommé votre sous-classe à la balise existante <application> . J'ai continué à essayer d'ajouter une autre <application>balise au manifeste et j'obtiendrais une exception.

Gimbl
la source
Salut, Gimbl. J'ai eu le même problème. J'ai également eu ma propre balise <application> et, lorsque j'essaye d'ajouter une autre balise <application>, j'ai eu le même problème que vous (message d'exception). Mais j'ai fait ce que vous avez mentionné, et cela n'a pas fonctionné. J'ajoute android: name = ". GlobalClass" à ma balise <application> mais cela ne fonctionne pas. Pouvez-vous expliquer en détail comment vous l'avez résolu ??
Sonhja
3
Bon <manifest> <application android: name = ". GlobalData"> </application> </manifest>. Mauvaise <manifest><application> </application> <application android: name = ". GlobalData"> </application> </manifest>
Gimbl
13

Je n'ai pas non plus trouvé comment spécifier la balise d'application, mais après beaucoup de recherches sur Google, cela est devenu évident à partir des documents du fichier manifeste: utilisez android: name, en plus de l'icône et de l'étiquette par défaut dans la strophe d'application.

android: name Nom complet d'une sous-classe d'application implémentée pour l'application. Lorsque le processus d'application est démarré, cette classe est instanciée avant l'un des composants de l'application.

La sous-classe est facultative; la plupart des applications n'en auront pas besoin. En l'absence d'une sous-classe, Android utilise une instance de la classe Application de base.

Mike Brown
la source
13

Qu'en est-il d'assurer la collecte de mémoire native avec de telles structures globales?

Les activités ont une onPause/onDestroy()méthode appelée destruction, mais la classe Application n'a pas d'équivalent. Quel mécanisme est recommandé pour garantir que les structures globales (en particulier celles contenant des références à la mémoire native) sont correctement récupérées lorsque l'application est supprimée ou que la pile de tâches est mise en arrière-plan?

user608578
la source
1
La solution évidente consiste à implémenter l' interface Closeable pour vos objets responsables des ressources natives et à vous assurer qu'ils sont gérés par une instruction try-with-resources ou autre. Dans le pire des cas, vous pouvez toujours utiliser un finaliseur d'objet.
bientôt
5

Il vous suffit de définir un nom d'application comme ci-dessous qui fonctionnera:

<application
  android:name="ApplicationName" android:icon="@drawable/icon">
</application>
Anand
la source
4

Comme il a été discuté ci-dessus, le système d'exploitation pourrait tuer l'APPLICATION sans aucune notification (il n'y a pas d'événement onDestroy), il n'y a donc aucun moyen de sauvegarder ces variables globales.

SharedPreferences pourrait être une solution SAUF si vous avez des variables STRUCTURÉES COMPLEXES (dans mon cas, j'avais un tableau d'entiers pour stocker les identifiants que l'utilisateur a déjà traités). Le problème avec les SharedPreferences est qu'il est difficile de stocker et de récupérer ces structures à chaque fois que les valeurs nécessaires.

Dans mon cas, j'avais un SERVICE en arrière-plan pour que je puisse déplacer ces variables là-bas et parce que le service a l'événement onDestroy, je pouvais enregistrer ces valeurs facilement.

Adorjan Princz
la source
onDestroy () n'est pas garanti d'être appelé même pour un service.
Apprenez OpenGL ES le
Oui, cela pourrait arriver mais uniquement en cas de situations critiques.
Adorjan Princz
4

Si certaines variables sont stockées dans sqlite et que vous devez les utiliser dans la plupart des activités de votre application. alors l'application est peut-être le meilleur moyen d'y parvenir. Recherchez les variables de la base de données au démarrage de l'application et stockez-les dans un champ. Ensuite, vous pouvez utiliser ces variables dans vos activités.

Alors, trouvez le bon chemin, et il n'y a pas de meilleur moyen.

user716653
la source
3

Vous pouvez avoir un champ statique pour stocker ce type d'état. Ou mettez-le dans le bundle de ressources et restaurez-le à partir de là onCreate (Bundle savedInstanceState). Assurez-vous simplement de bien comprendre le cycle de vie géré par l'application Android (par exemple, pourquoi login () est appelé lors du changement d'orientation du clavier).

yanchenko
la source
2

NE N'UTILISEZ PAS une autre <application>balise dans le fichier manifeste. Faites simplement un changement dans la <application>balise existante , ajoutez cette ligne android:name=".ApplicationName"ApplicationNamesera le nom de votre sous-classe (à utiliser pour stocker global) que vous êtes sur le point de créer.

donc, enfin, votre balise ONE AND ONLY <application> dans le fichier manifeste devrait ressembler à ceci: -

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.NoActionBar"
        android:name=".ApplicationName"
        >
kumar kundan
la source
1

vous pouvez utiliser Intents, Sqlite ou Shared Preferences. En ce qui concerne le stockage multimédia, comme les documents, les photos et les vidéos, vous pouvez créer les nouveaux fichiers à la place.

Raju yourPepe
la source
1

Vous pouvez le faire en utilisant deux approches:

  1. Utilisation de la classe Application
  2. Utilisation des préférences partagées

  3. Utilisation de la classe Application

Exemple:

class SessionManager extends Application{

  String sessionKey;

  setSessionKey(String key){
    this.sessionKey=key;
  }

  String getSessisonKey(){
    return this.sessionKey;
  }
}

Vous pouvez utiliser la classe ci-dessus pour implémenter la connexion dans votre MainActivity comme ci-dessous. Le code ressemblera à ceci:

@override 
public void onCreate (Bundle savedInstanceState){
  // you will this key when first time login is successful.
  SessionManager session= (SessionManager)getApplicationContext();
  String key=getSessisonKey.getKey();
  //Use this key to identify whether session is alive or not.
}

Cette méthode fonctionnera pour le stockage temporaire. Vous ne savez vraiment pas quand le système d'exploitation va tuer l'application, à cause de la mémoire insuffisante. Lorsque votre application est en arrière-plan et que l'utilisateur navigue dans une autre application qui nécessite plus de mémoire pour s'exécuter, votre application sera supprimée car le système d'exploitation accorde plus de priorité aux processus de premier plan qu'à l'arrière-plan. Par conséquent, votre objet d'application sera nul avant la déconnexion de l'utilisateur. Par conséquent, pour cela, je recommande d'utiliser la deuxième méthode spécifiée ci-dessus.

  1. Utilisation de préférences partagées.

    String MYPREF="com.your.application.session"
    
    SharedPreferences pref= context.getSharedPreferences(MyPREF,MODE_PRIVATE);
    
    //Insert key as below:
    
    Editot editor= pref.edit();
    
    editor.putString("key","value");
    
    editor.commit();
    
    //Get key as below.
    
    SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
    
    String key= getResources().getString("key");
Krishna
la source
0

Le résultat de l'activité est appelé avant la reprise. Déplacez donc votre vérification de connexion à la reprise et votre deuxième connexion peut être bloquée une fois que l'activité secomd a renvoyé un résultat positif. Le CV est appelé à chaque fois donc il n'y a pas de soucis à ce qu'il ne soit pas appelé la première fois.

user3044482
la source
0

L'approche du sous-classement a également été utilisée par le framework BARACUS. De mon point de vue application de sous- classement était destinée à fonctionner avec les cycles de vie d'Android; c'est ce que fait n'importe quel conteneur d'application. Au lieu d'avoir des globaux alors, j'enregistre des beans dans ce contexte et les laisse être injectés dans n'importe quelle classe gérable par le contexte. Chaque instance de bean injectée est en fait un singleton.

Voir cet exemple pour plus de détails

Pourquoi faire du travail manuel si vous pouvez en avoir tellement plus?

gorefest
la source
0
class GlobaleVariableDemo extends Application {

    private String myGlobalState;

    public String getGlobalState(){
     return myGlobalState;
    }
    public void setGlobalState(String s){
     myGlobalState = s;
    }
}

class Demo extends Activity {

@Override
public void onCreate(Bundle b){
    ...
    GlobaleVariableDemo appState = ((GlobaleVariableDemo)getApplicationContext());
    String state = appState.getGlobalState();
    ...
    }
}
Vaishali Sutariya
la source
0

Vous pouvez créer une classe qui étend la Applicationclasse, puis déclarer votre variable en tant que champ de cette classe et lui fournir une méthode getter.

public class MyApplication extends Application {
    private String str = "My String";

    synchronized public String getMyString {
        return str;
    }
}

Et puis pour accéder à cette variable dans votre activité, utilisez ceci:

MyApplication application = (MyApplication) getApplication();
String myVar = application.getMyString();
Amit Tiwari
la source