Variable globale Android

293

Comment puis-je créer des variables globales pour conserver des valeurs autour du cycle de vie de l'application, quelle que soit l'activité en cours d'exécution.

d-man
la source
Et pourquoi devrions-nous utiliser set and get (la réponse de Jeff Gilfelt)?! Pourquoi avons-nous simplement défini la valeur directement sur variable? comme ceci: public volatile statique String x; et pour définir la valeur: GeneralClass.x = valeur;
Dr.jacky

Réponses:

531

Vous pouvez étendre la android.app.Applicationclasse de base et ajouter des variables membres comme ceci:

public class MyApplication extends Application {

    private String someVariable;

    public String getSomeVariable() {
        return someVariable;
    }

    public void setSomeVariable(String someVariable) {
        this.someVariable = someVariable;
    }
}

Dans votre manifeste Android, vous devez déclarer la classe implémentant android.app.Application (ajoutez l' android:name=".MyApplication"attribut à la balise d'application existante):

<application 
  android:name=".MyApplication" 
  android:icon="@drawable/icon" 
  android:label="@string/app_name">

Ensuite, dans vos activités, vous pouvez obtenir et définir la variable comme suit:

// set
((MyApplication) this.getApplication()).setSomeVariable("foo");

// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();
Jeff Gilfelt
la source
4
aide géniale, j'applique vraiment.
d-man
6
Malheureusement, cela ne fonctionne pas pour moi. Veuillez confirmer qu'après cela, nous aurons deux balises <application> dans le manifeste. Droite? Parce qu'à certains endroits, j'ai entendu des gens dire que nous devons ajouter cela à la balise d'application existante. S'il vous plaît, aidez !!
Adil Malik
9
@AdilMalik Vous devez ajouter la balise android: name à la balise d'application existante
Marijn
2
Pourquoi ne pas simplement créer une classe avec des champs statiques publics sans avoir besoin d'accéder à un contexte?
Laserson
51
Cela ne devrait pas être une réponse correcte car cela peut conduire à un comportement imprévu et à NPE en raison du nettoyage de la mémoire. developerphil.com/dont-store-data-in-the-application-object
bakua
43

Vous pouvez utiliser un Singleton Patterncomme ceci:

package com.ramps;

public class MyProperties {
private static MyProperties mInstance= null;

public int someValueIWantToKeep;

protected MyProperties(){}

public static synchronized MyProperties getInstance() {
        if(null == mInstance){
            mInstance = new MyProperties();
        }
        return mInstance;
    }
}

Dans votre application, vous pouvez accéder à votre singleton de cette manière:

MyProperties.getInstance().someValueIWantToKeep
Rampes
la source
28
Que se passe-t-il si l'activité s'arrête et que l'utilisateur démarre une autre application et que cette mémoire est faible? C'est pourquoi Android a supprimé cet objet statique lorsque l'utilisateur a repris l'application et a trouvé cette référence statique nulle ???
d-man
4
Une statique est inutile entre les activités dans des processus séparés.
ateiob
3
cela ne fonctionnera pas si votre instance est récupérée. donc le bloc de code if (null == mInstance) {mInstance = new MyProperties (); } fonctionnera et une nouvelle instance sera retournée, ce qui réinitialisera les propriétés
Lalith B
1
@ Mr.Hyde Singleton n'est pas inutile, c'est juste que nous devons savoir quoi garder à l'intérieur du Singleton, si nous conservons d'énormes tableaux de bitmaps ou certaines collections, cela peut devenir dangereux. Prenez note de ce que vous gardez à l'intérieur du Singleton.
Lalith B
1
Je sais que je suis un peu en retard, mais pour les futurs lecteurs, nous pouvons stocker des valeurs dans SharedPreferences, SQLLite Database ou An Internal memory file. Ceux-ci auront tous la persistance des données même si l'application est fermée.
powernit
15

Cette variable globale fonctionne pour mon projet:

public class Global {
    public static int ivar1, ivar2;
    public static String svar1, svar2;
    public static int[] myarray1 = new int[10];
}


//  How to use other or many activity
Global.ivar1 = 10;

int i = Global.ivar1;
mahasam
la source
2
Mais comment le transmettez-vous à plusieurs activités?
Zapnologica
15
Ces statiques (au moins chaîne et tableau) peuvent être annulées par la machine virtuelle Android lorsque l'application est suspendue et que l'appareil a une mémoire faible.
Anton
4
@mahasam je ne pense pas que statique devrait être la bonne façon ... si ses seules activités, cela devrait être via le contexte de l'application. Sinon, une méthode singleton comme indiqué dans les autres réponses ci-dessus. statique couplera fortement le code et réduira également la testabilité
Punith Raj
14

Vous pouvez utiliser les préférences de l'application. Ils sont accessibles à partir de n'importe quelle activité ou morceau de code tant que vous transmettez l'objet Context, et ils sont privés de l'application qui les utilise, vous n'avez donc pas à vous soucier d'exposer des valeurs spécifiques à l'application, sauf si vous traitez avec routé dispositifs. Même ainsi, vous pouvez utiliser des schémas de hachage ou de chiffrement pour enregistrer les valeurs. De plus, ces préférences sont stockées d'une application exécutée à la suivante. Voici quelques exemples de code que vous pouvez consulter.

r1k0
la source
J'ai mis à jour le lien. Le projet a été hébergé sur Google Code et, comme nous le savons, il a été fermé. Le lien provient de Github.
r1k0
8

Il existe plusieurs façons de réaliser ce que vous demandez.

1.) Étendez la classe d'application et instanciez votre contrôleur et les objets de modèle là-bas.

public class FavoriteColorsApplication extends Application {

    private static FavoriteColorsApplication application;
    private FavoriteColorsService service;

    public FavoriteColorsApplication getInstance() {
        return application;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        application = this;
        application.initialize();
    }

    private void initialize() {
        service = new FavoriteColorsService();
    }

    public FavoriteColorsService getService() {
        return service;
    }

}

Ensuite, vous pouvez à tout moment appeler votre singleton à partir de votre objet Application personnalisé:

public class FavoriteColorsActivity extends Activity {

private FavoriteColorsService service = null;
private ArrayAdapter<String> adapter;
private List<String> favoriteColors = new ArrayList<String>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_favorite_colors);

    service = ((FavoriteColorsApplication) getApplication()).getService();
    favoriteColors = service.findAllColors();

    ListView lv = (ListView) findViewById(R.id.favoriteColorsListView);
    adapter = new ArrayAdapter<String>(this, R.layout.favorite_colors_list_item,
            favoriteColors);
    lv.setAdapter(adapter);
}

2.) Vous pouvez demander à votre contrôleur de créer une instance singleton de lui-même:

public class Controller {
    private static final String TAG = "Controller";
    private static sController sController;
    private Dao mDao;

    private Controller() {
        mDao = new Dao();    
    }

    public static Controller create() {
        if (sController == null) {
            sController = new Controller();
        }
        return sController;
    }
}

Ensuite, vous pouvez simplement appeler la méthode create à partir de n'importe quelle activité ou fragment et cela créera un nouveau contrôleur s'il n'en existe pas déjà, sinon il retournera le contrôleur préexistant.

3.) Enfin, il y a un cadre lisse créé à Square qui vous offre une injection de dépendance dans Android. Cela s'appelle Dague . Je n'entrerai pas dans la façon de l'utiliser ici, mais c'est très simple si vous avez besoin de ce genre de chose.

J'espère avoir donné suffisamment de détails sur la façon dont vous pouvez faire ce que vous espérez.

Dan Mikita
la source
6

Essayez comme ceci:

Créez une classe de données partagée:

SharedData.java

import android.app.Application;

/**
 * Created by kundan on 6/23/2015.
 */
public class Globals {


    private static Globals instance = new Globals();

    // Getter-Setters
    public static Globals getInstance() {
        return instance;
    }

    public static void setInstance(Globals instance) {
        Globals.instance = instance;
    }

    private String notification_index;


    private Globals() {

    }


    public String getValue() {
        return notification_index;
    }


    public void setValue(String notification_index) {
        this.notification_index = notification_index;
    }



}

Déclaré / initialiser une instance de classe globalement dans les classes où vous souhaitez définir / obtenir des données (en utilisant ce code avant la onCreate()méthode): -

Globals sharedData = Globals.getInstance();

Définir les données:

sharedData.setValue("kundan");

Obtenez des données:

String n = sharedData.getValue();
kumar kundan
la source
4

Vous pouvez créer un Global Classcomme ceci:

public class GlobalClass extends Application{

    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String aName) {
        name = aName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String aEmail) {
        email = aEmail;
    }
}

Définissez-le ensuite dans le manifeste:

<application
    android:name="com.example.globalvariable.GlobalClass" ....

Vous pouvez maintenant définir des valeurs pour une variable globale comme ceci:

final GlobalClass globalVariable = (GlobalClass) getApplicationContext();
globalVariable.setName("Android Example context variable");

Vous pouvez obtenir ces valeurs comme ceci:

final GlobalClass globalVariable = (GlobalClass) getApplicationContext();
final String name  = globalVariable.getName();

Veuillez trouver un exemple complet de ce blog Variables globales

san88
la source
3
// My Class Global Variables  Save File Global.Java
public class Global {
    public static int myVi; 
    public static String myVs;
}

// How to used on many Activity

Global.myVi = 12;
Global.myVs = "my number";
........
........
........
int i;
int s;
i = Global.myVi;
s = Global.myVs + " is " + Global.myVi;
mahasam
la source
1
Pourquoi publiez-vous deux réponses dans la même question? Vous pouvez le modifier en un seul.
Kunu
2

J'ai vérifié pour une réponse similaire, mais celles données ici ne correspondent pas à mes besoins. Je trouve quelque chose qui, de mon point de vue, correspond à ce que vous recherchez. Le seul point noir possible est une question de sécurité (ou peut-être pas) car je ne connais pas la sécurité.

Je suggère d'utiliser Interface (pas besoin d'utiliser Class avec constructeur et ainsi de suite ...), car il suffit de créer quelque chose comme:

public interface ActivityClass {

    public static final String MYSTRING_1 = "STRING";

    public static final int MYINT_1 = 1;

}

Ensuite, vous pouvez accéder partout dans vos classes en utilisant ce qui suit:

int myInt = ActivityClass.MYINT_1;
String myString = ActivityClass.MYSTRING_1;
Alexandre
la source
1

Techniquement, cela ne répond pas à la question, mais je recommanderais d'utiliser la base de données Room au lieu d'une variable globale. https://developer.android.com/topic/libraries/architecture/room.html Même si vous n'avez besoin que de stocker une variable globale et ce n'est pas grave et quoi, mais l'utilisation de la base de données Room est la plus élégante , façon native et bien supportée de conserver les valeurs tout au long du cycle de vie de l'activité. Cela permettra d'éviter de nombreux problèmes, en particulier l'intégrité des données. Je comprends que la base de données et la variable globale sont différentes, mais veuillez utiliser Room pour la maintenance du code, la stabilité de l'application et l'intégrité des données.

hexicle
la source
1

Utilisez SharedPreferences pour stocker et récupérer des variables globales.

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String userid = preferences.getString("userid", null);
Coen Damen
la source
0

Si possible, vous devez déclarer les variables dont vous avez besoin pour maintenir en vie qui n'ont pas été effacées par Garbage Collector ou Décharger par OS dans le fichier .so Pour ce faire, vous devez coder en C / C ++ et compiler dans le fichier lib .so et chargez-le dans votre MainActivity.

Tran Huu Phuoc
la source
1
Le code natif est un moyen douloureux de conserver des données dans la RAM, et pas mieux que les staticvariables Java .
Jerry101
Je ne vois pas l'intérêt de cette approche. Pouvez-vous expliquer dans quel cas c'est une bonne idée?
miva2
-1
import android.app.Application;

public class Globals extends Application
{
    private static Globals instance = null;
    private static int RecentCompaignID;
    private static int EmailClick;
    private static String LoginPassword;
    static String loginMemberID;
    private static String CompaignName = "";
    private static int listget=0;
    //MailingDetails
    private static String FromEmailadd="";
    private static String FromName="";
    private static String ReplyEmailAdd="";
    private static String CompaignSubject="";
    private static int TempId=0;
    private static int ListIds=0;

    private static String HTMLContent="";
    @Override
    public void onCreate() 
    {
        super.onCreate();
        instance = this;
    }

    public static Globals getInstance()
    {
        return instance;
    }

    public void setRecentCompaignID(int objRecentCompaignID)
    {
        RecentCompaignID = objRecentCompaignID;
    }

    public int getRecentCompaignID() 
    {
        return RecentCompaignID;
    }

    public void setLoginMemberID(String objloginMemberID) 
    {
        loginMemberID = objloginMemberID;
    }

    public String getLoginMemberID() 
    {
        return loginMemberID;
    }

    public void setLoginMemberPassword(String objLoginPassword)
    {
        LoginPassword = objLoginPassword;
    }

    public String getLoginMemberPassword()
    {
        return LoginPassword;
    }

    public void setEmailclick(int id)
    {
        EmailClick = id;
    }

    public int getEmailClick() 
    {
        return EmailClick;
    }
    public void setCompaignName(String objCompaignName)
    {
        CompaignName=objCompaignName;
    }
    public String getCompaignName()
    {
        return CompaignName;
    }
    public void setlistgetvalue(int objlistget)
    {
        listget=objlistget;
    }
    public int getlistvalue()
    {
        return listget;
    }
    public void setCompaignSubject(String objCompaignSubject)
    {
         CompaignSubject=objCompaignSubject;
    }
    public String getCompaignSubject()
    {
        return CompaignSubject;
    }
    public void setHTMLContent(String objHTMLContent)
    {
        HTMLContent=objHTMLContent;
    }
    public String getHTMLContent()
    {
        return HTMLContent;
    }
    public void setListIds(int objListIds)
    {
        ListIds=objListIds;
    }
    public int getListIds()
    {
        return ListIds;
    }
    public void setReplyEmailAdd(String objReplyEmailAdd)
    {
        ReplyEmailAdd=objReplyEmailAdd;
    }
    public String getReplyEmailAdd()
    {
        return ReplyEmailAdd;
    }
    public void setFromName(String objFromName)
    {
        FromName=objFromName;
    }
    public String getFromName()
    {
        return FromName;
    }
    public void setFromEmailadd(String objFromEmailadd)
    {
        FromEmailadd=objFromEmailadd;
    }
    public String getFromEmailadd()
    {
        return FromEmailadd;
    }
}
user2054528
la source
-5

Facile!!!!

Les variables auxquelles vous souhaitez accéder en tant que variable globale, vous pouvez les déclarer en tant que variables statiques. Et maintenant, vous pouvez accéder à ces variables en utilisant

classname.variablename;

public class MyProperties {
private static MyProperties mInstance= null;

static int someValueIWantToKeep;

protected MyProperties(){}

public static synchronized MyProperties getInstance(){
    if(null == mInstance){
        mInstance = new MyProperties();
    }
    return mInstance;
}

}

MyProperites.someValueIWantToKeep;

C'est tout! ;)

Dinesh Padwal
la source
Je ne sais pas pourquoi il a été autant voté; en comparant avec d'autres réponses votées par le net, je vois que cela utilise correctement (iirc) synchronizedsur le statique getInstance()alors que d'autres ne le font pas. voté en conséquence.
user2297550