Globale Android-Variable

293

Wie kann ich eine globale Variable erstellen? Behalten Sie die Werte im gesamten Lebenszyklus der Anwendung bei, unabhängig davon, welche Aktivität ausgeführt wird.

D-Mann
quelle
Und warum sollten wir set and get verwenden (Jeff Gilfelt's Antwort)?! Warum setzen wir den Wert einfach direkt auf Variable? wie folgt: public volatile static String x; und um den Wert festzulegen: GeneralClass.x = Wert;
Dr. Jacky

Antworten:

531

Sie können die Basisklasse erweitern android.app.Applicationund Elementvariablen wie folgt hinzufügen:

public class MyApplication extends Application {

    private String someVariable;

    public String getSomeVariable() {
        return someVariable;
    }

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

In Ihrem Android-Manifest müssen Sie die Klasse deklarieren, die android.app.Application implementiert (fügen Sie das android:name=".MyApplication"Attribut dem vorhandenen Anwendungs-Tag hinzu):

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

Dann können Sie in Ihren Aktivitäten die Variable wie folgt abrufen und einstellen:

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

// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();
Jeff Gilfelt
quelle
4
Super Hilfe, ich bewerbe mich wirklich.
D-Mann
6
Leider funktioniert es bei mir nicht. Bitte bestätigen Sie, dass danach zwei <application> -Tags im Manifest sind. Richtig? Denn an einigen Stellen hörte ich Leute sagen, dass wir dies zu einem vorhandenen Anwendungs-Tag hinzufügen müssen. Bitte helfen Sie !!
Adil Malik
9
@ AdilMalik Sie müssen das Android: Name-Tag zum vorhandenen Anwendungs-Tag hinzufügen
Marijn
2
Warum nicht einfach eine Klasse mit öffentlichen statischen Feldern erstellen, ohne auf einen Kontext zugreifen zu müssen?
Laserson
50
Dies sollte keine korrekte Antwort sein, da dies aufgrund der Speicherbereinigung zu unvorhergesehenem Verhalten und zu NPE führen kann. developerphil.com/dont-store-data-in-the-application-object
bakua
43

Sie können Folgendes verwenden Singleton Pattern:

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;
    }
}

In Ihrer Anwendung können Sie auf folgende Weise auf Ihren Singleton zugreifen:

MyProperties.getInstance().someValueIWantToKeep
Rampen
quelle
28
Was ist, wenn die Aktivität angehalten wurde und der Benutzer eine andere Anwendung gestartet hat und während dieser Erinnerung niedrig war? Deshalb hat Android dieses statische Objekt entfernt, als der Benutzer die Anwendung wieder aufnahm und diese statische Referenz null fand.
D-Man
4
Eine Statik ist für Aktivitäten in separaten Prozessen nutzlos.
Ateiob
3
Dies funktioniert nicht, wenn Ihre Instanz Müll gesammelt wird. also der Codeblock if (null == mInstance) {mInstance = new MyProperties (); } wird funktionieren und eine neue Instanz wird zurückgegeben, die die Eigenschaften zurücksetzt
Lalith B
1
@ Mr.Hyde Singleton ist nicht nutzlos, es ist nur so, dass wir wissen müssen, was im Singleton aufbewahrt werden soll. Wenn wir riesige Bitmap-Arrays oder einige Sammlungen aufbewahren, kann dies gefährlich werden. Notieren Sie sich, was Sie im Singleton aufbewahren.
Lalith B
1
Ich weiß, dass ich etwas spät dran bin, aber für zukünftige Leser können wir Werte in SharedPreferences, SQLLite-Datenbank oder einer internen Speicherdatei speichern. Diese haben alle Datenpersistenz, auch wenn die Anwendung geschlossen ist.
Powernit
15

Diese globale Variable funktioniert für mein Projekt:

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
quelle
2
Aber wie geben Sie es dann an mehrere Aktivitäten weiter?
Zapnologica
15
Diese Statik (mindestens Zeichenfolge und Array) wird möglicherweise von der Android-VM auf Null gesetzt, wenn die Anwendung angehalten wird und das Gerät über wenig Speicher verfügt.
Anton
4
@ Mahasam Ich denke nicht, dass statisch der richtige Weg sein sollte ... wenn es nur Aktivitäten sind, sollte es über den Anwendungskontext erfolgen. Andernfalls ein Singleton-Weg, wie in anderen Antworten oben angegeben. statisch wird den Code stark koppeln und verringert auch die Testbarkeit
Punith Raj
14

Sie können Anwendungseinstellungen verwenden. Sie können von jeder Aktivität oder jedem Code aus aufgerufen werden, solange Sie das Context-Objekt weitergeben, und sie sind für die Anwendung, die sie verwendet, privat. Sie müssen sich also keine Gedanken über die Offenlegung anwendungsspezifischer Werte machen, es sei denn, Sie befassen sich mit Routing Geräte. Trotzdem können Sie Hashing- oder Verschlüsselungsschemata verwenden, um die Werte zu speichern. Diese Einstellungen werden auch von einem Anwendungslauf zum nächsten gespeichert. Hier sind einige Codebeispiele, die Sie sich ansehen können.

r1k0
quelle
Ich habe den Link aktualisiert. Das Projekt wurde auf Google Code gehostet und wie wir wissen, wurde es geschlossen. Der Link ist von Github.
r1k0
8

Es gibt verschiedene Möglichkeiten, wie Sie das erreichen können, wonach Sie fragen.

1.) Erweitern Sie die Anwendungsklasse und instanziieren Sie dort Ihre Controller- und Modellobjekte.

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;
    }

}

Dann können Sie Ihren Singleton jederzeit von Ihrem benutzerdefinierten Anwendungsobjekt aus aufrufen:

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.) Sie können Ihren Controller einfach eine Singleton-Instanz von sich selbst erstellen lassen:

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;
    }
}

Dann können Sie die create-Methode einfach aus einer beliebigen Aktivität oder einem beliebigen Fragment aufrufen und einen neuen Controller erstellen, falls noch keiner vorhanden ist. Andernfalls wird der bereits vorhandene Controller zurückgegeben.

3.) Schließlich gibt es bei Square ein schickes Framework, das Ihnen die Abhängigkeitsinjektion in Android ermöglicht. Es heißt Dolch . Ich werde hier nicht darauf eingehen, wie man es benutzt, aber es ist sehr schlau, wenn man so etwas braucht.

Ich hoffe, ich habe genug Details angegeben, wie Sie das tun können, was Sie sich erhoffen.

Dan Mikita
quelle
6

Versuchen Sie es wie folgt:

Erstellen Sie eine gemeinsam genutzte Datenklasse:

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;
    }



}

Deklariert / initiiert eine Instanz einer Klasse global in den Klassen, in denen Sie Daten festlegen / abrufen möchten (unter Verwendung dieses Codes vor der onCreate()Methode): -

Globals sharedData = Globals.getInstance();

Daten einstellen:

sharedData.setValue("kundan");

Daten empfangen:

String n = sharedData.getValue();
Kumar Kundan
quelle
4

Sie können Folgendes erstellen Global Class:

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;
    }
}

Dann definieren Sie es im Manifest:

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

Jetzt können Sie Werte wie folgt auf eine globale Variable setzen:

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

Sie können diese Werte wie folgt erhalten:

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

Ein vollständiges Beispiel finden Sie in diesem Blog Global Variables

san88
quelle
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
quelle
1
Warum veröffentlichen Sie zwei Antworten in derselben Frage? Sie können es zu einem bearbeiten.
Kunu
2

Ich habe nach einer ähnlichen Antwort gesucht, aber die hier angegebenen entsprechen nicht meinen Anforderungen. Ich finde etwas, das aus meiner Sicht das ist, wonach Sie suchen. Der einzig mögliche schwarze Punkt ist eine Sicherheitsfrage (oder vielleicht auch nicht), da ich nichts über Sicherheit weiß.

Ich schlage vor, Interface zu verwenden (Klasse muss nicht mit Konstruktor verwendet werden und so ...), da Sie nur Folgendes erstellen müssen:

public interface ActivityClass {

    public static final String MYSTRING_1 = "STRING";

    public static final int MYINT_1 = 1;

}

Dann können Sie überall in Ihren Klassen auf Folgendes zugreifen:

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

Technisch beantwortet dies die Frage nicht, aber ich würde empfehlen, die Raumdatenbank anstelle einer globalen Variablen zu verwenden. https://developer.android.com/topic/libraries/architecture/room.html Auch wenn Sie "nur" eine globale Variable speichern müssen und es keine große Sache ist und was nicht, ist die Verwendung der Room-Datenbank die eleganteste , native und gut unterstützte Methode, um Werte über den Lebenszyklus der Aktivität zu erhalten. Dies hilft, viele Probleme zu vermeiden, insbesondere die Integrität von Daten. Ich verstehe, dass Datenbank und globale Variable unterschiedlich sind, aber bitte verwenden Sie Room aus Gründen der Code-Wartung, App-Stabilität und Datenintegrität.

Hexikel
quelle
1

Verwenden Sie SharedPreferences, um globale Variablen zu speichern und abzurufen.

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

Wenn möglich, sollten Sie die Variablen deklarieren, die Sie am Leben erhalten müssen, die von Garbage Collector nicht gelöscht oder von OS in Datei .so entladen wurden. Dazu müssen Sie mit C / C ++ codieren und in die Datei .so lib und kompilieren Laden Sie es in Ihre MainActivity.

Tran Huu Phuoc
quelle
1
Native Code ist eine schmerzhafte Methode, um Daten im RAM zu speichern, und dies nicht besser als Java- staticVariablen.
Jerry101
Ich verstehe den Sinn dieses Ansatzes nicht. Können Sie näher erläutern, in welchem ​​Fall dies eine gute Idee ist?
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
quelle
-5

Einfach!!!!

Diese Variablen, auf die Sie als globale Variable zugreifen möchten, können Sie als statische Variablen deklarieren. Und jetzt können Sie mit auf diese Variablen zugreifen

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;

Das ist es! ;)

Dinesh Padwal
quelle
nicht sicher, warum es so sehr herabgestimmt wurde; Im Vergleich zu einigen anderen Antworten mit Netz-Upvoted sehe ich, dass dies korrekt (iirc) synchronizedfür die Statik verwendet wird, getInstance()während andere dies nicht tun. entsprechend abgestimmt.
user2297550